SDUI make it easy to implement Server Driven UI pattern on flutter.
Kind like HTML... but not really.
Here is an example of JSON returned by the URL POST http://myapp.herokuapp.com/screens/profile
:
{
"type": "Screen",
"appBar": {
"type": "AppBar",
"attributes": {
"title": "Profile"
}
},
"child": {
"type": "Form",
"attributes": {
"padding": 10
},
"children": [
{
"type": "Input",
"attributes": {
"name": "first_name",
"value": "Ray",
"caption": "First Name",
"maxLength": 30
}
},
{
"type": "Input",
"attributes": {
"name": "last_name",
"value": "Sponsible",
"caption": "Last Name",
"maxLength": 30
}
},
{
"type": "Input",
"attributes": {
"name": "email",
"value": "ray.sponsible@gmail.com",
"caption": "Email *",
"required": true
}
},
{
"type": "Input",
"attributes": {
"type": "date",
"name": "birth_date",
"caption": "Date of Birth"
}
},
{
"type": "Input",
"attributes": {
"type": "Submit",
"name": "submit",
"caption": "Create Profile"
},
"action": {
"type": "Command",
"url": "https://myapp.herokuapp.com/commands/save-profile",
"prompt": {
"type": "Dialog",
"attributes": {
"type": "confirm",
"title": "Confirmation",
"message": "Are you sure you want to change your profile?"
}
}
}
}
]
}
}
import 'package:flutter/material.dart';
import 'package:sdui/sdui.dart';
void main() async {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(title: 'Demo', initialRoute: '/', routes: _routes());
}
Map<String, WidgetBuilder> _routes() =>
{
'/': (context) =>
const DynamicRoute(
provider: HttpRouteContentProvider(
'http://www.myapp.com/screens/profile'))
};
}
Screen | Date Picker | Alert Dialog |
---|---|---|
In Flutter, UI is composed of a hierarchy of Widgets. A widget is a visual element on a screen.
SDUI described widgets with the following json structure:
{
"type": "...",
"attributes": {
"padding": 12,
"color": "#ff0000",
...
},
"children": [
...
]
}
type
: indicates the type of widgetattributes
: key/value pair of the attributes of the widget. Ex: caption
, color
, padding
, spacing
etc.children
: The list of children widgetssduiErrorState
: Function for building the error state.sduiLoadingState
: Function for building the loading state.sduiProgressIndicator
: Function for building the progress indicator.sduiRouteObserver
: Route observer that reload each page on navigation.sduiAnalytics
: Analytics class.
See SDUIAnalyticssduiCameras
: List of available cameras. Empty by default, must be initialized the applicationWith actions, you can:
SDUI described actions with the following json structure:
{
"type": "...",
"attributes": {
...
},
...
"action": {
"type": "...",
"url": "...",
"prompt": {
"type": "...",
"title": "Confirmation",
"message": "Are you sure you want to change your profile?"
}
}
}
type
: Defines the type of action:
Route
: To redirect to another routePage
: To redirect to another page, in the context of [PageView]Command
: Remote action to execute. The screen is associated with a URL that will execute the command, and
redirect the user to the next screenShare
: Share a message to user via email/messenger/whatsapp etc.Navigate
: Navigate user to a web pageurl
: is the URL associated with the action
route:/..
: redirect users to previous routeroute:/~
: redirect users to 1st routeroute:/<ROUTE_NAME>
redirect user the a named route. (Ex: route:/checkout
)http://
or https
redirect user to a server driven pagepage:/<PAGE_NUMBER>
: redirect users to a given page. <PAGE_NUMBER>
is the page index (starting with 0
).replacement
: For type=Route
, this indicate if we replace the current view or navigate.parameters
: Parameters to add to the URL where to redirect tomessage
: Message to shareprompt
: Shows a Dialog before execute the action
type
: The type of prompt (Exemple: Confirm
, Error
, Warning
, Information
)title
: Title of the alert box to openmessage
: Message to display to the userYou can integrate your own widget into sdui
.
SDUIWidget
This is an example of widget that render a text with a margin and padding. The widget has the following attributes
text
: The text to displaypadding
: The padding valuemargin
: The margin value class MyWidget extends SDUIWidget {
String text = '';
double padding = 10.0;
double margin = 10.0;
/// This method will be called by [SDUIParser] to read the widget attributes from the JSON data
@override
SDUIWidget fromJson(Map<String, dynamic>? json) {
text = json?['caption'] ?? '';
margin = json?['margin'] ?? 10.0;
padding = json?['padding'] ?? 10.0;
return this;
}
/// This method will be called when rendering the page to create the Flutter widget
@override
Widget toWidget(BuildContext context) =>
Container(
padding: EdgeInsets.all(padding),
margin: EdgeInsets.all(margin),
child: Text(
text,
style:
const TextStyle(fontWeight: FontWeight.bold, color: Colors.red),
),
);
}
The Widget is registered into SDUI and associated with the type MyWidget
void main() async {
// Register 3rd party widget
SDUIWidgetRegistry.getInstance().register('MyWidget', () => MyWidget());
runApp(constMyApp());
}
class MyApp extends StatelessWidget {
// ...
}
Here is an example of JSON with our 3rd party widget
{
"type": "Screen",
"appBar": {
"type": "AppBar",
"attributes": {
"title": "Home"
}
},
"child": {
"type": "Center",
"children": [
{
"type": "MyWidget",
"attributes": {
"caption": "3rd Party Widget",
"padding": 5.0,
"margin": 5.0
}
}
]
}
}