Flutter自定义UI组件插件sdui的使用
Flutter自定义UI组件插件sdui的使用
简介
SDUI
是一个用于在 Flutter 中实现服务驱动界面(Server Driven UI)模式的插件。通过这种方式,服务器可以决定渲染哪些组件,并以 JSON 格式描述这些组件。
- 服务器端:负责决定渲染哪些组件。
- 客户端:解析 JSON 并构建相应的 Flutter 组件。
示例
服务器端 JSON 示例
以下是一个示例 JSON,从 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?"
}
}
}
}
]
}
}
客户端 Flutter 代码
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](/user/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 |
---|---|---|
组件库
导航组件
Dialog
AppBar
Page
PageView
Screen
布局组件
Center
Column
Container
Expanded
FittedBox
Flexible
GridView
Positioned
Row
Stack
SingleChildScrollView
Spacer
图片/图标组件
CarouselSlider
CircleAvatar
Icon
IconButton
Image
PhotoView
输入组件
Button
Camera
DropdownButton
DropdownMenuItem
Form
IconButton
Input
ListView
ListItem
ListItemSwitch
MoneyText
MoneyWithKeyboard
MoneyWithSlider
PinWidthKeyboard
QrImage
QrView
Radio
RadioGroup
SearchableDropdown
Text
其他组件
Badge
Chip
ExpandablePanel
Html
全局变量
sduiErrorState
: 构建错误状态的方法。sduiLoadingState
: 构建加载状态的方法。sduiProgressIndicator
: 构建进度指示器的方法。sduiRouteObserver
: 导航时重新加载每个页面的路由观察者。sduiAnalytics
: 分析类。sduiCameras
: 可用摄像头列表,默认为空,需要在应用启动时初始化。
动作
动作允许你执行以下操作:
- 在服务器上执行命令(例如保存用户配置文件、删除用户帐户等)。
- 导航到另一个屏幕。
- 向用户显示消息。
示例 JSON 结构
{
"type": "...",
"attributes": {
...
},
...
"action": {
"type": "...",
"url": "...",
"prompt": {
"type": "...",
"title": "Confirmation",
"message": "Are you sure you want to change your profile?"
}
}
}
自定义组件
你可以将自定义组件集成到 sdui
中。
步骤 1:创建 SDUIWidget
实例
以下是一个示例,展示如何创建一个带有边距和填充的文本组件。该组件具有以下属性:
text
: 要显示的文本。padding
: 填充值。margin
: 边距值。
class MyWidget extends SDUIWidget {
String text = '';
double padding = 10.0;
double margin = 10.0;
/// 这个方法由 [SDUIParser] 调用来从 JSON 数据读取组件属性
[@override](/user/override)
SDUIWidget fromJson(Map<String, dynamic>? json) {
text = json?['caption'] ?? '';
margin = json?['margin'] ?? 10.0;
padding = json?['padding'] ?? 10.0;
return this;
}
/// 这个方法在渲染页面时调用以创建 Flutter 组件
[@override](/user/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),
),
);
}
步骤 2:注册组件
将组件注册到 SDUI
并与类型 MyWidget
关联。
void main() async {
// 注册第三方组件
SDUIWidgetRegistry.getInstance().register('MyWidget', () => MyWidget());
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Demo',
initialRoute: '/',
routes: _routes(),
debugShowCheckedModeBanner: false,
navigatorObservers: [sduiRouteObserver],
);
}
Map<String, WidgetBuilder> _routes() => {
'/': (context) => const DynamicRoute(
provider: HttpRouteContentProvider(
'http://10.0.2.2:8080' /* 移除端点 - 替换为您的端点 */
)),
};
}
步骤 3:在 JSON 中添加组件
以下是一个包含第三方组件的 JSON 示例:
{
"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
}
}
]
}
}
完整示例代码
import 'package:flutter/material.dart';
import 'package:sdui/sdui.dart';
import 'my_widget.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 注册第三方组件
SDUIWidgetRegistry.getInstance().register('MyWidget', () => MyWidget());
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Demo',
initialRoute: '/',
routes: _routes(),
debugShowCheckedModeBanner: false,
navigatorObservers: [sduiRouteObserver],
);
}
Map<String, WidgetBuilder> _routes() => {
'/': (context) => const DynamicRoute(
provider: HttpRouteContentProvider(
'http://10.0.2.2:8080' /* 移除端点 - 替换为您的端点 */
)),
};
}
更多关于Flutter自定义UI组件插件sdui的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter自定义UI组件插件sdui的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中集成和使用自定义UI组件插件sdui
的代码示例。由于sdui
不是一个实际存在的公开插件(假设它是一个自定义插件),我将展示一个假设的集成和使用过程。通常,集成第三方插件的过程大致相同,包括在pubspec.yaml
中添加依赖、导入包以及使用插件提供的组件。
1. 在pubspec.yaml
中添加依赖
首先,你需要在你的pubspec.yaml
文件中添加sdui
作为依赖。请注意,由于sdui
是假设的,这里用example_custom_ui
代替。
dependencies:
flutter:
sdk: flutter
example_custom_ui: ^1.0.0 # 假设的版本号
然后运行flutter pub get
来安装依赖。
2. 导入sdui
包
在你的Dart文件中导入sdui
包。由于我们假设的包名是example_custom_ui
,导入语句如下:
import 'package:example_custom_ui/example_custom_ui.dart';
3. 使用sdui
提供的组件
假设sdui
提供了一个名为CustomButton
的按钮组件,你可以在你的Flutter应用中这样使用它:
import 'package:flutter/material.dart';
import 'package:example_custom_ui/example_custom_ui.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Custom UI Component Demo'),
),
body: Center(
child: CustomButton(
onPressed: () {
// 按钮点击时的回调
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Button Pressed!')),
);
},
label: 'Click Me',
// 假设的自定义属性
color: Colors.green,
fontSize: 20.0,
),
),
);
}
}
4. 假设的CustomButton
组件的实现(插件开发者视角)
虽然这不是用户需要做的,但了解组件的实现有助于理解如何使用它。以下是假设的CustomButton
组件的简单实现:
// 假设在example_custom_ui包中
import 'package:flutter/material.dart';
class CustomButton extends StatelessWidget {
final VoidCallback? onPressed;
final String label;
final Color color;
final double fontSize;
const CustomButton({
Key? key,
required this.onPressed,
required this.label,
this.color = Colors.blue,
this.fontSize = 18.0,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: onPressed,
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(color),
overlayColor: MaterialStateProperty.resolveWith<Color?>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.pressed)) {
return color.withOpacity(0.7);
}
return null;
},
),
textStyle: MaterialStateProperty.all(
TextStyle(fontSize: fontSize),
),
),
child: Text(label),
);
}
}
总结
通过上述步骤,你可以在Flutter项目中集成并使用假设的自定义UI组件插件sdui
(在这里用example_custom_ui
代替)。这包括在pubspec.yaml
中添加依赖、导入包以及使用插件提供的组件。实际使用中,你需要根据具体的插件文档进行相应的调整。