flutter_dynamic
flutter_dynamic 是一个能动态创建Flutter应用的引擎。flutter_dynamic不但支持写UI,还支持写代码逻辑。
EN: The flutter_dynamic is an engine that create flutter application dynamically. flutter_dynamic not only supports writing UI, but also writing code logic.
153768151@qq.com - feel free to contact me
Best practice
<img src="https://upload-images.jianshu.io/upload_images/3868052-24e08253efeff413.gif?imageMogr2/auto-orient/strip" width="320px"/>
目录 Table of contents
- General-info概况
- Install 安装
- Get-started 使用
- Grammar 语法
- Widgets 组件
- Customize-Widget 自定义组件
- Customize-Grammar 自定义语法
- Contact 联系
General-info
Install
step 1. Depend on it
dependencies:
yz_flutter_dynamic:
git:
url: https://github.com/fisherjoe/flutter_dynamic.git
ref: master
Or
Download or clone the code to the local:
dependencies:
yz_flutter_dynamic:
path: your/code/path
Or
Do as example of code.
step 2. Use it
Use as common flutter plugin in flutter project.
step 3. Import it
Now in your Flutter code, you can use:
import 'package:yz_flutter_dynamic/main.dart';
Get-started
Hello world
import 'package:flutter/material.dart';
import 'package:yz_flutter_dynamic/main.dart';
class Helloworld extends StatefulWidget {
@override
_HelloworldState createState() => _HelloworldState();
}
class _HelloworldState extends State<Helloworld> {
@override
Widget build(BuildContext context) {
return YZDynamic.buildWidget(
context,
hwDsl,
);
}
}
Map hwDsl =
{
"xKey": "",
"widgetName": "Scaffold",
"props": {
"appBar": {
"xKey": "",
"widgetName": "AppBar",
"props": {
"title": {
"widgetName": "Text",
"props": {"data": "Navigator"}
}
}
},
"body": {
"xKey": "",
"widgetName": "SafeArea",
"props": {
"child": {
"xKey": "_Text",
"widgetName": "Text",
"props": {
"data": "Hello world"
}
}
}
}
}
};
How to create your dynamic widget
step1: How to create widget UI
invoke
YZDynamic.buildPage(context, json, preConfig: preConfig);
json
{
"xKey": "globalKeyOfWidget",
"widgetName": "Container",
"props": {
"padding": "[10, 10, 0, 0]",
"height": "44",
"child": {
"widgetName": "Text",
"props": {
"data": "Data of Text widget",
"color": "0xfff1f1f1"
}
}
},
"xEvents": [
{
"eventType": "onClick",
"code": '''
[code...]
'''
},
"xVar": {
}
]
}
xKey
:The globalkey of widget to find the widget.widgetName
: The type of widget.xEvents
: The event of the widget support "onClick" type now. The value support grammar as Grammar 语法xVar
: Define the variable of widget.-
props
: The properties of the widget which property is the same as system of widget's property. There are two types of props value such as :- string: The type of property value like "color" "width" should use string type {"widget":"100", "color": "#ff000000"}. Specially the type of EdgeInsets will be "[10, 20, 30, 40]" for "[left, top, right, bottom]". The enum of type will be like "multiline" for TextInputType.multiline
- map: The type of property value like "Size" will be {"color":"", "width":""}.
step2: How to create page
invoke build page
YZDynamic.buildPage(context, json, preConfig: preConfig);
invoke present page
YZDynamic.handle(context, json, preConfig: preConfig)
json
{
"page": {
"key": "",
"presentMode": "",
"state": {
"initState": [
],
"build": [
],
"dispose": [
]
},
"xVar":{},
"rootWidget": {}
}
}
key
:The globalkey of page.presentMode
: The present mode of page. The value is "dialog / navpage".Use for YZDynamic.handle invocation only.state
: The lifecycle of page which is as good as the system StatefulWidget.xVar
: Define the variable of widget.rootWidget
: The root widget of page. It is similay to the return widget of StatefulWidget's build method.
step3: How to write code
- code of property: such as event config {"eventType": "onClick", "code": ``` [code...] ```}
- other value: start with "code:", such as {"color": ``` code: [code...] ```}
step4: How to use variables
- 在page/widget对象的xVar属性中定义,如:"xVar": {"variableName": "variableValue"};
- 在code中定义,如:```<c:variableName>=Int(10); <w:variableName2>=String(Hellow world)```;
注意:伪代码code变量没有变量类型。如果赋值时没有强制说明类型则自动默认为字符串,使用的时候会根据特定需要自动转换。
step5: How to implement event
Grammar
在源代码的example里有写动态页面的伪代码语法,如图所示:
Widgets
Container
Text
TextField
Column
Expanded
Image
Padding
Row
SafeArea
SingleChildScrollView
Scaffold
AppBar
RawMaterialButton
SizedBox
Dialog
Customize-Widget
Define CustomerWidget
/// CustomerWidget handler
class YZCustomerWidgetHandler extends YZDynamicBasicWidgetHandler {
@override
String get widgetName => 'CustomerWidget';
@override
Widget build(Map<String, dynamic> json, {Key key, BuildContext buildContext}) {
return _Builder(json, key:key);
}
}
class _Builder extends YZDynamicBaseWidget {
final Map<String, dynamic> json;
_Builder(this.json, {Key key}): super(json, key: key);
@override
_BuilderState createState() => _BuilderState();
}
class _BuilderState extends YZDynamicWidgetBasicState<_Builder> {
//Deal with props / 处理控件属性
Map props;
Alignment _alignment;
@override
void initState() {
super.initState();
//Deal with props / 处理控件属性
props = super.config.props;
_alignment = YZDinamicWidgetUtils.alignmentAdapter(props["alignment"]);
}
@override
Widget build(BuildContext context) {
Widget _widget;
CustomerWidget _subwidget = CustomerWidget(
alignment: _alignment,
);
//Deal with events / 处理事件
_widget = super.buildWithEvents(_subwidget, super.config.xEvents);
return _widget;
}
@override
void registerActions() {
//Deal with action / 处理事件实现
actionFunctions['setState'] = stateSetter;
}
void stateSetter({
Map params,
YZDynamicRequest request,
List<YZDynamicActionRule> rules,
Map localVariables,
State state,
}) {
print('Execute xAction: ${this.runtimeType} setState');
if (mounted) {
setState(() {});
}
}
}
Register CustomerWidget
YZDynamicCommon.reginsterWidgetHandler(YZCustomerWidgetHandler)
User CustomerWidget
{
"xKey": "globalKeyOfWidget",
"widgetName": "CustomerWidget",
"props": {
"alignment": "[10, 10, 0, 0]"
},
"xEvents": [
{
"eventType": "onClick",
"code": '''
[code...]
'''
},
"xVar": {
}
]
}
Customize-Grammar
Define action
/*
* Custum action
* 自定义 action
*/
class YZToastHandler extends YZDynamicPublicActionHandler{
@override
void action(BuildContext context, {
Map params,
YZDynamicRequest request,
List<YZDynamicActionRule> rules,
Map localVariables,
State state,
}) {
String tip = params['tip'];
Fluttertoast.showToast(
msg: tip,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
);
}
@override
String get actionName => 'yzToast';
}
Register action
YZDynamicCommon.reginsterPublicActionHandler(YZToastHandler());
User action
yzToast(tip:content);
Contact
Created by 153768151@qq.com - feel free to contact me