├── .gitignore ├── .idea ├── libraries │ └── Dart_SDK.xml ├── modules.xml ├── runConfigurations │ └── example_lib_main_dart.xml └── workspace.xml ├── .metadata ├── CHANGELOG.md ├── LICENSE ├── README.md ├── README_CH.md ├── doc ├── bestpratice.md └── widgets.md ├── example ├── .gitignore ├── .metadata ├── README.md ├── android │ ├── .gitignore │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── yingzi_flutter_dynamicpage_example │ │ │ │ │ └── MainActivity.kt │ │ │ └── res │ │ │ │ ├── drawable │ │ │ │ └── launch_background.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ └── values │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle ├── ios │ ├── .gitignore │ ├── Flutter │ │ ├── .last_build_id │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Podfile │ ├── Podfile.lock │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ └── contents.xcworkspacedata │ └── Runner │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── Runner-Bridging-Header.h ├── lib │ ├── demo │ │ ├── actions.dart │ │ ├── adapter.dart │ │ ├── bestpratice.dart │ │ ├── config.dart │ │ ├── dsl.dart │ │ └── helloworld.dart │ ├── grammar │ │ ├── base.dart │ │ ├── bool.dart │ │ ├── controlflow.dart │ │ ├── dsl.dart │ │ ├── list.dart │ │ ├── map.dart │ │ ├── math.dart │ │ ├── number.dart │ │ ├── operators_lo.dart │ │ ├── operators_re.dart │ │ ├── set.dart │ │ ├── string.dart │ │ ├── unittesting.dart │ │ └── user_code.dart │ └── main.dart ├── pubspec.lock ├── pubspec.yaml └── test │ └── widget_test.dart ├── lib ├── main.dart ├── pages │ ├── basic │ │ ├── lifecycle.dart │ │ ├── page.dart │ │ └── utils.dart │ ├── builder.dart │ ├── custompage.dart │ ├── formpage.dart │ ├── formwidget.dart │ └── model │ │ └── page_config.dart ├── tools │ ├── action.dart │ ├── actions │ │ ├── all.dart │ │ ├── control_flow.dart │ │ ├── core.dart │ │ ├── iterable.dart │ │ ├── list.dart │ │ ├── map.dart │ │ ├── math.dart │ │ ├── number.dart │ │ ├── regexp.dart │ │ ├── router.dart │ │ ├── set.dart │ │ └── string.dart │ ├── code.dart │ ├── code │ │ └── lexical_analyzer.dart │ ├── common.dart │ ├── network.dart │ ├── rule.dart │ └── variable.dart └── widgets │ ├── alert_dialog.dart │ ├── align.dart │ ├── all.dart │ ├── app_bar.dart │ ├── basic.dart │ ├── basic │ ├── action.dart │ ├── data.dart │ ├── event.dart │ ├── handler.dart │ ├── utils.dart │ └── widget.dart │ ├── button.dart │ ├── center.dart │ ├── checkbox.dart │ ├── clip_rrect.dart │ ├── column.dart │ ├── container.dart │ ├── dialog.dart │ ├── divider.dart │ ├── expanded.dart │ ├── flexible.dart │ ├── form.dart │ ├── gesture_detector.dart │ ├── image.dart │ ├── listView.dart │ ├── model │ └── widget_config.dart │ ├── offstage.dart │ ├── padding.dart │ ├── positioned.dart │ ├── radio.dart │ ├── row.dart │ ├── safe_area.dart │ ├── scaffold.dart │ ├── scroll_view.dart │ ├── simple_dialog.dart │ ├── stack.dart │ ├── statefulwidget.dart │ ├── statelesswidget.dart │ ├── text.dart │ ├── text_field.dart │ └── wrap.dart ├── pubspec.lock ├── pubspec.yaml ├── test └── yz_flutter_dynamic_test.dart └── yz_flutter_dynamic.iml /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .dart_tool/ 3 | 4 | .packages 5 | .pub/ 6 | 7 | build/ 8 | -------------------------------------------------------------------------------- /.idea/libraries/Dart_SDK.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/runConfigurations/example_lib_main_dart.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: f30b7f4db93ee747cd727df747941a28ead25ff5 8 | channel: stable 9 | 10 | project_type: plugin 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.0.1 2 | 3 | * TODO: Describe initial release. 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | TODO: Add your license here. 2 | -------------------------------------------------------------------------------- /doc/bestpratice.md: -------------------------------------------------------------------------------- 1 | ## Best Practice (最佳实践) 2 | > 此文档我们将一步步按展示如何使用flutter_dynamic完成动态创建页面的过程。如果想看真实的效果,请运行example工程里的Best Practice。 3 | 4 | 5 | 6 | 7 | 8 | ### Step 1 9 | > 先创建具有两个输入框和一个按扭的描述UI的数据; 10 | 11 | 12 | TextFieldA 13 | ```dart 14 | var _textFieldA = { 15 | "xKey": "_TextFieldA", 16 | "widgetName": "TextField", 17 | "props": { 18 | "style": { 19 | "color": "0xff000000", 20 | "fontWeight": "bold" 21 | }, 22 | "keyboardType": "number", 23 | "value": "Input", 24 | "decoration" : { 25 | "hint": "I am TextFieldA", 26 | "border": { 27 | "color": "0xffffff00", 28 | "width": "2" 29 | } 30 | } 31 | } 32 | }; 33 | ``` 34 | 35 | TextFieldB 36 | ```dart 37 | var _textFieldB = { 38 | "xKey": "_TextFieldB", 39 | "widgetName": "TextField", 40 | "props": { 41 | "style": { 42 | "color": "0xff000000", 43 | "fontWeight": "bold" 44 | }, 45 | "value": "Input", 46 | "decoration" : { 47 | "hint": "I am TextFieldB", 48 | "border": { 49 | "color": "0xffffff00", 50 | "width": "2" 51 | } 52 | } 53 | } 54 | }; 55 | ``` 56 | 57 | button 58 | ```dart 59 | var _button = { 60 | "xKey": "_RawMaterialButton", 61 | "widgetName": "RawMaterialButton", 62 | "props": { 63 | "fillColor": "0xfff2f2f2", 64 | "padding": "[10,0,10,0]", 65 | "child": { 66 | "type": "sysWidget", 67 | "widgetName": "Text", 68 | "props": { 69 | "data": "'RawMaterialButton'. Click", 70 | "color": "0xff123456", 71 | "backgroundColor": "0xff00ff00", 72 | "fontSize": "16", 73 | "fontWeight": "bold", 74 | "lineHeight": "1.2" 75 | } 76 | } 77 | } 78 | }; 79 | ``` 80 | 81 | ### Step 2 82 | > 为了更好地演示效果,我们需要将Step 1的json数据放在Scaffold类型的Material widget里,并通过单独的页面来展示它: 83 | 84 | 85 | ```dart 86 | var _dslRootWidget = { 87 | "xKey": "", 88 | "widgetName": "Scaffold", 89 | "props": { 90 | "appBar": { 91 | "xKey": "", 92 | "widgetName": "AppBar", 93 | "props": { 94 | "title": { 95 | "widgetName": "Text", 96 | "props": {"data": "Navigator"} 97 | } 98 | } 99 | }, 100 | "body": { 101 | "xKey": "", 102 | "widgetName": "SafeArea", 103 | "props": { 104 | "child": { 105 | "xKey": "", 106 | "widgetName": "Column", 107 | "props": { 108 | "children": [ 109 | _textFieldA, 110 | _textFieldB, 111 | _button 112 | ] 113 | } 114 | } 115 | } 116 | } 117 | } 118 | }; 119 | ``` 120 | 121 | ### Step 3 122 | > 通过Step 1和Step 2,我们就可以创建一个完整的UI了。具体效果见example/lib/main.dart里的Best Practice演示效果: 123 | 124 | ```dart 125 | 126 | Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext contex){ 127 | return YZDynamic.buildWidget(context, bestPraticeDsl, preConfig: null); 128 | })); 129 | 130 | ``` 131 | 132 | ### Step 4 133 | > 如果点击button的时候需要获取TextFieldA和TextFieldB的值,我们该如何实现呢?很简单,在button json里加入如下定义就可以了: 134 | 135 | event 136 | ```dart 137 | "xEvents": [ 138 | { 139 | "eventType": "onClick", 140 | "code": ''' 141 | =; 142 | action:yzToast(tip:) 143 | ''' 144 | } 145 | ] 146 | 147 | ``` 148 | 149 | and button json will show as: 150 | ```dart 151 | var _button = { 152 | "xKey": "_RawMaterialButton", 153 | "widgetName": "RawMaterialButton", 154 | "props": { 155 | "fillColor": "0xfff2f2f2", 156 | "padding": "[10,0,10,0]", 157 | "child": { 158 | "type": "sysWidget", 159 | "widgetName": "Text", 160 | "props": { 161 | "data": "Button", 162 | "color": "0xff123456", 163 | "backgroundColor": "0xff00ff00", 164 | "fontSize": "16", 165 | "fontWeight": "bold", 166 | "lineHeight": "1.2" 167 | } 168 | } 169 | }, 170 | "xEvents": [ 171 | { 172 | "eventType": "onClick", 173 | "code": ''' 174 | =; 175 | action:yzToast(tip:) 176 | ''' 177 | } 178 | ] 179 | }; 180 | ``` 181 | 182 | ### Step 5 183 | > Building more wonderful application, Please read [Document](https://github.com/Yingzi-Technology/flutter_dynamic) 184 | -------------------------------------------------------------------------------- /doc/widgets.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yingzi-Technology/flutter_dynamic/dd0f3b58dbfccca095835220a2335a5b0b851e21/doc/widgets.md -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | /build/ 32 | 33 | # Web related 34 | lib/generated_plugin_registrant.dart 35 | 36 | # Exceptions to above rules. 37 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 38 | -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 0b8abb4724aa590dd0f429683339b1e045a1594d 8 | channel: unknown 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # yingzi_flutter_dynamicpage_example 2 | 3 | Demonstrates how to use the yz_flutter_dynamic plugin. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 28 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | lintOptions { 36 | disable 'InvalidPackage' 37 | } 38 | 39 | defaultConfig { 40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 41 | applicationId "com.example.yingzi_flutter_dynamicpage_example" 42 | minSdkVersion 16 43 | targetSdkVersion 28 44 | versionCode flutterVersionCode.toInteger() 45 | versionName flutterVersionName 46 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 47 | } 48 | 49 | buildTypes { 50 | release { 51 | // TODO: Add your own signing config for the release build. 52 | // Signing with the debug keys for now, so `flutter run --release` works. 53 | signingConfig signingConfigs.debug 54 | } 55 | } 56 | } 57 | 58 | flutter { 59 | source '../..' 60 | } 61 | 62 | dependencies { 63 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 64 | testImplementation 'junit:junit:4.12' 65 | androidTestImplementation 'androidx.test:runner:1.1.1' 66 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' 67 | } 68 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 8 | 12 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/com/example/yingzi_flutter_dynamicpage_example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.yingzi_flutter_dynamicpage_example 2 | 3 | import androidx.annotation.NonNull; 4 | import io.flutter.embedding.android.FlutterActivity 5 | import io.flutter.embedding.engine.FlutterEngine 6 | import io.flutter.plugins.GeneratedPluginRegistrant 7 | 8 | class MainActivity: FlutterActivity() { 9 | override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { 10 | GeneratedPluginRegistrant.registerWith(flutterEngine); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yingzi-Technology/flutter_dynamic/dd0f3b58dbfccca095835220a2335a5b0b851e21/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yingzi-Technology/flutter_dynamic/dd0f3b58dbfccca095835220a2335a5b0b851e21/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yingzi-Technology/flutter_dynamic/dd0f3b58dbfccca095835220a2335a5b0b851e21/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yingzi-Technology/flutter_dynamic/dd0f3b58dbfccca095835220a2335a5b0b851e21/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yingzi-Technology/flutter_dynamic/dd0f3b58dbfccca095835220a2335a5b0b851e21/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.5.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip 7 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /example/ios/Flutter/.last_build_id: -------------------------------------------------------------------------------- 1 | 83bcff09dfccf1b706d26d99ca6b484e -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - fluttertoast (0.0.2): 4 | - Flutter 5 | - Toast 6 | - Toast (4.0.0) 7 | 8 | DEPENDENCIES: 9 | - Flutter (from `Flutter`) 10 | - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) 11 | 12 | SPEC REPOS: 13 | trunk: 14 | - Toast 15 | 16 | EXTERNAL SOURCES: 17 | Flutter: 18 | :path: Flutter 19 | fluttertoast: 20 | :path: ".symlinks/plugins/fluttertoast/ios" 21 | 22 | SPEC CHECKSUMS: 23 | Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c 24 | fluttertoast: 6122fa75143e992b1d3470f61000f591a798cc58 25 | Toast: 91b396c56ee72a5790816f40d3a94dd357abc196 26 | 27 | PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c 28 | 29 | COCOAPODS: 1.10.1 30 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yingzi-Technology/flutter_dynamic/dd0f3b58dbfccca095835220a2335a5b0b851e21/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yingzi-Technology/flutter_dynamic/dd0f3b58dbfccca095835220a2335a5b0b851e21/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yingzi-Technology/flutter_dynamic/dd0f3b58dbfccca095835220a2335a5b0b851e21/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yingzi-Technology/flutter_dynamic/dd0f3b58dbfccca095835220a2335a5b0b851e21/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yingzi-Technology/flutter_dynamic/dd0f3b58dbfccca095835220a2335a5b0b851e21/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yingzi-Technology/flutter_dynamic/dd0f3b58dbfccca095835220a2335a5b0b851e21/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yingzi-Technology/flutter_dynamic/dd0f3b58dbfccca095835220a2335a5b0b851e21/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yingzi-Technology/flutter_dynamic/dd0f3b58dbfccca095835220a2335a5b0b851e21/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yingzi-Technology/flutter_dynamic/dd0f3b58dbfccca095835220a2335a5b0b851e21/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yingzi-Technology/flutter_dynamic/dd0f3b58dbfccca095835220a2335a5b0b851e21/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yingzi-Technology/flutter_dynamic/dd0f3b58dbfccca095835220a2335a5b0b851e21/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yingzi-Technology/flutter_dynamic/dd0f3b58dbfccca095835220a2335a5b0b851e21/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yingzi-Technology/flutter_dynamic/dd0f3b58dbfccca095835220a2335a5b0b851e21/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yingzi-Technology/flutter_dynamic/dd0f3b58dbfccca095835220a2335a5b0b851e21/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yingzi-Technology/flutter_dynamic/dd0f3b58dbfccca095835220a2335a5b0b851e21/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yingzi-Technology/flutter_dynamic/dd0f3b58dbfccca095835220a2335a5b0b851e21/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yingzi-Technology/flutter_dynamic/dd0f3b58dbfccca095835220a2335a5b0b851e21/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yingzi-Technology/flutter_dynamic/dd0f3b58dbfccca095835220a2335a5b0b851e21/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | yingzi_flutter_dynamicpage_example 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" -------------------------------------------------------------------------------- /example/lib/demo/actions.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-09-19 13:45:48 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-11-19 11:18:56 6 | */ 7 | 8 | import 'package:fluttertoast/fluttertoast.dart'; 9 | import 'package:yz_flutter_dynamic/main.dart'; 10 | 11 | /* 12 | * Custum action 13 | * 自定义 action 14 | */ 15 | class YZToastHandler extends YZDynamicPublicActionHandler{ 16 | @override 17 | void action(BuildContext context, { 18 | Map params, 19 | YZDynamicRequest request, 20 | List rules, 21 | Map localVariables, 22 | State state, 23 | }) { 24 | String tip = params['tip']; 25 | Fluttertoast.showToast( 26 | msg: tip, 27 | toastLength: Toast.LENGTH_SHORT, 28 | gravity: ToastGravity.CENTER, 29 | timeInSecForIosWeb: 1, 30 | backgroundColor: Colors.red, 31 | textColor: Colors.white, 32 | fontSize: 16.0 33 | ); 34 | } 35 | 36 | @override 37 | String get actionName => 'yzToast'; 38 | 39 | } -------------------------------------------------------------------------------- /example/lib/demo/adapter.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2021-07-15 13:43:44 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2021-07-15 13:52:47 6 | * @Describe: 组件属性适配 7 | */ 8 | 9 | // Text widget adapter 10 | Map yzTextWidgetAdapter(Map json) { 11 | 12 | Map _json = {}; 13 | for (var key in json.keys) { 14 | _json[key] = json[key]; 15 | } 16 | 17 | if (_json['props'] != null && 18 | (_json['props'] is Map) && 19 | _json['props']['style'] == null) { 20 | 21 | _json['props']['style'] = { 22 | "color" : json['props']['fontColor'], 23 | "background" : json['props']['bgColor'], 24 | "fontSize" : json['props']['fontSize'], 25 | "fontWeight" : json['props']['fontWeight'], 26 | "fontStyle" : json['props']['fontStyle'], 27 | "letterSpacing" : json['props']['letterSpacing'], 28 | "wordSpacing" : json['props']['wordSpacing'], 29 | "height" : json['props']['height'], 30 | }; 31 | 32 | } 33 | 34 | return _json; 35 | 36 | } 37 | -------------------------------------------------------------------------------- /example/lib/demo/bestpratice.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-12-21 16:54:50 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-12-21 17:58:51 6 | */ 7 | 8 | Map bestPraticeDsl = _dslRootWidget; 9 | 10 | var _dslRootWidget = { 11 | "xKey": "", 12 | "widgetName": "Scaffold", 13 | "props": { 14 | "appBar": { 15 | "xKey": "", 16 | "widgetName": "AppBar", 17 | "props": { 18 | "title": { 19 | "widgetName": "Text", 20 | "props": {"data": "Navigator"} 21 | } 22 | } 23 | }, 24 | "body": { 25 | "xKey": "", 26 | "widgetName": "SafeArea", 27 | "props": { 28 | "child": { 29 | "xKey": "", 30 | "widgetName": "Column", 31 | "props": { 32 | "children": [ 33 | _textFieldA, 34 | _textFieldB, 35 | _button, 36 | _button2 37 | ] 38 | } 39 | } 40 | } 41 | } 42 | } 43 | }; 44 | 45 | var _textFieldA = { 46 | "xKey": "_TextFieldA", 47 | "widgetName": "TextField", 48 | "props": { 49 | "value": "I am TextFieldA", 50 | "style": { 51 | "color": "0xff000000", 52 | "fontWeight": "bold" 53 | }, 54 | "keyboardType": "number", 55 | "decoration" : { 56 | "hint": "I am TextFieldA" 57 | } 58 | } 59 | }; 60 | 61 | var _textFieldB = { 62 | "xKey": "_TextFieldB", 63 | "widgetName": "TextField", 64 | "props": { 65 | "style": { 66 | "color": "0xff000000", 67 | "fontWeight": "bold" 68 | }, 69 | "decoration" : { 70 | "hint": "I am TextFieldB" 71 | } 72 | } 73 | }; 74 | 75 | var _button = { 76 | "xKey": "_RawMaterialButton", 77 | "widgetName": "RawMaterialButton", 78 | "props": { 79 | "fillColor": "0xfff2f2f2", 80 | "padding": "[10,0,10,0]", 81 | "child": { 82 | "type": "sysWidget", 83 | "widgetName": "Text", 84 | "props": { 85 | "data": "Button", 86 | "color": "0xff123456", 87 | "backgroundColor": "0xff00ff00", 88 | "fontSize": "16", 89 | "fontWeight": "bold", 90 | "lineHeight": "1.2" 91 | } 92 | } 93 | }, 94 | "xEvents": [ 95 | // { 96 | // "eventType": "onClick", 97 | // "code": ''' 98 | // =; 99 | // action:yzToast(tip:) 100 | // ''' 101 | // }, 102 | { 103 | "name": "", 104 | "eventType": "onClick", 105 | "actions": [ 106 | { 107 | "actionName":"yzToast", 108 | "params":{"tip":""}, 109 | "targetKey": "" 110 | } 111 | ], 112 | "code": "" 113 | } 114 | ] 115 | }; 116 | 117 | var _button2 = { 118 | "xKey": "_RawMaterialButton2", 119 | "widgetName": "RawMaterialButton", 120 | "props": { 121 | "fillColor": "0xfff2f2f2", 122 | "padding": "[10,0,10,0]", 123 | "child": { 124 | "type": "sysWidget", 125 | "widgetName": "Text", 126 | "props": { 127 | "data": "访问传入页面的回调方法", 128 | "color": "0xff123456", 129 | "backgroundColor": "0xff00ff00", 130 | "fontSize": "16", 131 | "fontWeight": "bold", 132 | "lineHeight": "1.2" 133 | } 134 | } 135 | }, 136 | "xEvents": [ 137 | { 138 | "name": "", 139 | "eventType": "onClick", 140 | "actions": [ 141 | { 142 | "actionName":"outDoorAction" 143 | } 144 | ], 145 | "code": "" 146 | } 147 | ] 148 | }; 149 | 150 | -------------------------------------------------------------------------------- /example/lib/demo/config.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-09-03 09:24:58 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2021-07-15 13:45:13 6 | **/ 7 | 8 | import 'actions.dart'; 9 | 10 | import 'package:yz_flutter_dynamic/main.dart'; 11 | 12 | import 'adapter.dart'; 13 | 14 | /// The third part config 15 | 16 | bool isDynamicpageConfigFPFInit = false; 17 | 18 | dynamicpageConfigDemo() { 19 | 20 | if (isDynamicpageConfigFPFInit == true) return; 21 | isDynamicpageConfigFPFInit = true; 22 | 23 | //Register the third part widget 24 | //注册扩展的第三方控件 25 | // YZDynamicCommon.reginsterWidgetHandler(...); 26 | 27 | //Register the third part action 28 | //注册扩展的第三方action 29 | YZDynamicCommon.reginsterPublicActionHandler(YZToastHandler()); 30 | 31 | YZDynamicCommon.addWidgetConfigInterceptor('Text', yzTextWidgetAdapter); 32 | 33 | //注册网络库 34 | //Register the network lib 35 | // YZDynamicCommon.network = YZDynamicDataNetworkFPF.getInstance(); 36 | 37 | } 38 | 39 | -------------------------------------------------------------------------------- /example/lib/grammar/base.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-12-02 14:43:45 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-12-02 17:42:52 6 | */ 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:yz_flutter_dynamic/main.dart'; 10 | 11 | import 'dsl.dart'; 12 | 13 | class UTBaseState extends State { 14 | 15 | external List getItem(); 16 | external String get getTitle; 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | return Scaffold( 21 | appBar: AppBar(title: Text(this.getTitle)), 22 | body: Padding( 23 | padding: EdgeInsets.all(10), 24 | child: SingleChildScrollView( 25 | child: Column( 26 | crossAxisAlignment: CrossAxisAlignment.start, 27 | children: this.getItem(), 28 | ) 29 | ) 30 | ), 31 | ); 32 | } 33 | 34 | Widget createItem(String kw, String code) { 35 | TextEditingController control = TextEditingController.fromValue( 36 | TextEditingValue( 37 | text: 38 | '''$code''' 39 | ) 40 | ); 41 | return Column( 42 | crossAxisAlignment: CrossAxisAlignment.start, 43 | children: [ 44 | Container( 45 | margin: EdgeInsets.only(bottom: 10), 46 | child: FlatButton( 47 | color: Colors.black12, 48 | child: Text(kw, style: TextStyle(fontSize: 14, color: Colors.lightBlue)), 49 | onPressed: (){ 50 | YZDynamic.handle( 51 | context, getDemoDsl(control.text) 52 | ); 53 | } 54 | ) 55 | ), 56 | TextField( 57 | maxLines: null, 58 | decoration: InputDecoration( 59 | contentPadding: EdgeInsets.zero 60 | ), 61 | scrollPadding: EdgeInsets.zero, 62 | textAlign: TextAlign.start, 63 | controller: control, 64 | ) 65 | ], 66 | ); 67 | } 68 | 69 | } -------------------------------------------------------------------------------- /example/lib/grammar/bool.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yangyiting 3 | * @Date: 2021-03-01 09:29:56 4 | * @Last Modified by: yangyiting 5 | * @Last Modified time: 2021-03-01 11:38:37 6 | */ 7 | 8 | import 'package:flutter/material.dart'; 9 | 10 | import 'base.dart'; 11 | 12 | class UTBool extends StatefulWidget { 13 | @override 14 | _UTBoolState createState() => _UTBoolState(); 15 | } 16 | 17 | class _UTBoolState extends UTBaseState { 18 | 19 | String get getTitle => "bool"; 20 | 21 | List getItem() { 22 | return [ 23 | createItem('bool', '=action:bool(true)'), 24 | createItem('Sys.bool', '=action:Sys.bool(true)'), 25 | createItem('Sys.bool', '=action:Sys.bool(false)'), 26 | createItem('Sys.bool.toString', '=action:bool.toString(false)'), 27 | ]; 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /example/lib/grammar/controlflow.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-12-01 11:20:04 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-12-02 18:20:56 6 | */ 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:yz_flutter_dynamic/main.dart'; 10 | 11 | import 'base.dart'; 12 | 13 | class UTIfElse extends StatefulWidget { 14 | @override 15 | _UTIfElseState createState() => _UTIfElseState(); 16 | } 17 | 18 | class _UTIfElseState extends UTBaseState { 19 | 20 | String get getTitle => "if else operators"; 21 | 22 | List getItem() { 23 | return [ 24 | createItem("if", 25 | ''' 26 | var:=bool(true); 27 | if () { 28 | var:=if; 29 | var:=var: 30 | } 31 | '''), 32 | createItem("if else", 33 | ''' 34 | var:=bool(true); 35 | if () { 36 | var:=if; 37 | var:=var: 38 | } else { 39 | var:=else; 40 | var:=var: 41 | } 42 | '''), 43 | createItem("if else if", 44 | ''' 45 | var:=bool(true); 46 | var:=bool(false); 47 | var:=; 48 | if () { 49 | var:=if; 50 | var:=var: 51 | } else if (var:) { 52 | var:=elseif; 53 | var:=var: 54 | } else { 55 | var:=else; 56 | var:=var: 57 | } 58 | ''') 59 | ]; 60 | } 61 | 62 | } 63 | 64 | 65 | class UTSwitchCase extends StatefulWidget { 66 | @override 67 | _UTSwitchCaseState createState() => _UTSwitchCaseState(); 68 | } 69 | 70 | class _UTSwitchCaseState extends UTBaseState { 71 | 72 | String get getTitle => "switch case operators"; 73 | 74 | List getItem() { 75 | return [ 76 | createItem("switch case", 77 | ''' 78 | var:=int(2); 79 | switch () { 80 | case 1: { 81 | var:=1; 82 | var:=var:; 83 | break; 84 | } 85 | case int(2): { 86 | var:=2; 87 | var:=var:; 88 | break; 89 | } 90 | default: { 91 | var:=default; 92 | var:=var:; 93 | break; 94 | } 95 | } 96 | ''') 97 | ]; 98 | } 99 | 100 | } 101 | 102 | class UTForloop extends StatefulWidget { 103 | @override 104 | _UTForloopState createState() => _UTForloopState(); 105 | } 106 | 107 | class _UTForloopState extends UTBaseState { 108 | 109 | String get getTitle => "forloop operators"; 110 | 111 | List getItem() { 112 | return [ 113 | createItem("for", 114 | ''' 115 | var:=List(a,b,c); 116 | var:=int(3); 117 | for ( = 0; i < var:; ++) { 118 | var:=action:List.valueOfIndex(list:, index:); 119 | var:=var:; 120 | } 121 | ''') 122 | ]; 123 | } 124 | 125 | } 126 | 127 | class UTWhile extends StatefulWidget { 128 | @override 129 | _UTWhileState createState() => _UTWhileState(); 130 | } 131 | 132 | class _UTWhileState extends UTBaseState { 133 | 134 | String get getTitle => "while operators"; 135 | 136 | List getItem() { 137 | return [ 138 | createItem("while", 139 | ''' 140 | var:=int(0); 141 | while (Sys.<=(, int(10))) { 142 | var:=num.+(, 1); 143 | }; 144 | var:=var:; 145 | ''') 146 | ]; 147 | } 148 | 149 | } -------------------------------------------------------------------------------- /example/lib/grammar/dsl.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-12-01 12:00:04 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-12-02 16:26:07 6 | */ 7 | 8 | getDemoDsl(String code) { 9 | 10 | code = code.trim(); 11 | 12 | var result; 13 | if (code.startsWith('userCode:')) { 14 | result = code; 15 | } else { 16 | result = '''code: 17 | $code 18 | var:=`The result is: var:`; 19 | action:Sys.print(var:); 20 | action:String(var:) 21 | '''; 22 | 23 | if (!code.startsWith("var")) { 24 | code = "var:=$code;"; 25 | } else if (!code.endsWith(';')){ 26 | code = '$code;'; 27 | } 28 | } 29 | 30 | var text = { 31 | "xKey": "_Text", 32 | "type": "sysWidget", 33 | "widgetName": "Text", 34 | "props": { 35 | "data": "var:", 36 | }, 37 | "xVar": { 38 | "result": result 39 | } 40 | }; 41 | 42 | var tip = { 43 | "xKey": "_TextTip", 44 | "type": "sysWidget", 45 | "widgetName": "Text", 46 | "props": { 47 | "data": "如果希望显示语句结果,需要把语句结果赋值给,如=num.+(1,2);\n\r输出结果如下:\n\r", 48 | } 49 | }; 50 | 51 | var _dslRootWidget = { 52 | "xKey": "", 53 | "widgetName": "Scaffold", 54 | "props": { 55 | "appBar": { 56 | "xKey": "", 57 | "widgetName": "AppBar", 58 | "props": { 59 | "title": { 60 | "widgetName": "Text", 61 | "props": {"data": "Demo"} 62 | } 63 | } 64 | }, 65 | "body": { 66 | "xKey": "", 67 | "widgetName": "Column", 68 | "props": { 69 | "children": [ 70 | { 71 | "xKey": "", 72 | "widgetName": "SingleChildScrollView", 73 | "props": { 74 | "child": { 75 | "xKey": "", 76 | "widgetName": "Column", 77 | "props": { 78 | "children": [ 79 | tip, 80 | text, 81 | ] 82 | } 83 | } 84 | } 85 | } 86 | ] 87 | } 88 | } 89 | } 90 | }; 91 | 92 | Map demoDsl = 93 | { 94 | "page": { 95 | "presentMode": "dialog", 96 | "rootWidget": _dslRootWidget 97 | } 98 | }; 99 | 100 | return demoDsl; 101 | 102 | } 103 | 104 | -------------------------------------------------------------------------------- /example/lib/grammar/map.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-12-01 11:20:04 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-12-02 17:40:03 6 | */ 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:yz_flutter_dynamic/main.dart'; 10 | 11 | import 'base.dart'; 12 | 13 | class UTMap extends StatefulWidget { 14 | @override 15 | _UTMapState createState() => _UTMapState(); 16 | } 17 | 18 | class _UTMapState extends UTBaseState { 19 | 20 | String get getTitle => "Map"; 21 | 22 | List getItem() { 23 | return [ 24 | createItem("Map", 'action:Map({"k1":"v1", "k2":"v2"});'), 25 | createItem("MapEntry", 'var:=action:MapEntry(key:k1,value:v1);'), 26 | createItem("Map.valueOfKey", 'var:=Map({"k1":"v1", "k2":"v2"});\nvar:=action:Map.valueOfKey(map:var:, key:k1);'), 27 | createItem("Map.isEmpty", 'var:=Map({"k1":"v1", "k2":"v2"});\nvar:=action:Map.isEmpty(map:var:);'), 28 | createItem("Map.isNotEmpty", 'var:=Map({"k1":"v1", "k2":"v2"});\nvar:=action:Map.isNotEmpty(map:var:);'), 29 | createItem("Map.length", 'var:=Map({"k1":"v1", "k2":"v2"});\nvar:=action:Map.length(map:var:);'), 30 | createItem("Map.containsValue", 'var:=Map({"k1":"v1", "k2":"v2"});\nvar:=action:Map.containsValue(map:var:, value:v1);'), 31 | createItem("Map.containsKey", 'var:=Map({"k1":"v1", "k2":"v2"});\nvar:=action:Map.containsKey(map:var:, key:k1);'), 32 | createItem("Map.remove", 'var:=Map({"k1":"v1", "k2":"v2"});\naction:Map.remove(map:var:, key:k1));\nvar:=var:'), 33 | createItem("Map.clear", 'var:=Map({"k1":"v1", "k2":"v2"});\naction:Map.clear(map:var:));\nvar:=var:'), 34 | createItem("Map.keys", 'var:=Map({"k1":"v1", "k2":"v2"});\nvar:=action:Map.keys(map:var:));'), 35 | createItem("Map.values", 'var:=Map({"k1":"v1", "k2":"v2"});\nvar:=action:Map.values(map:var:));'), 36 | createItem("Map.entries", 'var:=Map({"k1":"v1", "k2":"v2"});\nvar:=action:Map.entries(map:var:);\nvar:=action:Iterable.elementAt(iterable:var:,index:0);'), 37 | createItem("Map.addAll", 'var:=Map({"k1":"v1", "k2":"v2"});\nvar:=Map({"k3":"v3", "k4":"v4"});\naction:Map.addAll(map:var:,other:var:,));\nvar:=var:'), 38 | createItem("Map.toString", 'var:=Map({"k1":"v1", "k2":"v2"});\nvar:=action:Map.toString(map:var:);'), 39 | createItem("Map.from", 'var:=Map({"k1":"v1", "k2":"v2"});\nvar:=action:Map.from(other:var:);'), 40 | createItem("Map.of", 'var:=Map({"k1":"v1", "k2":"v2"});\nvar:=action:Map.of(other:var:);'), 41 | createItem("Map.identity", 'var:=action:Map.identity();'), 42 | createItem("Map.fromIterable",'var:=List(1,2,3,4);\nvar:=action:Map.fromIterable(entries:var:)'), 43 | createItem("Map.fromIterables",'var:=List(1,2,3,4);\nvar:=List(a,b,c,d);\nvar:=action:Map.fromIterables(keys:var:,values:var:)'), 44 | // FIXME: addEntries、fromEntries;不传入泛型如何解决这个问题 45 | // createItem("Map.fromEntries", 'var:=action:MapEntry(key:k3,value:v3);\nvar:=action:List();\naction:List.add(value:var:,list:var:);\nvar:=action:Map.fromEntries(entries:var:);'), 46 | // createItem("Map.addEntries", 'var:=Map({"k1":"v1", "k2":"v2"});\nvar:=MapEntry(key:k3,value:v3);\nvar:=List();\naction:List.add(value:var:,list:var:);\naction:Map.addEntries(newEntries:var:, map:var:);\nvar:=var:'), 47 | createItem("Map.unmodifiable", 'var:=Map({"k1":"v1", "k2":"v2"});\nvar:=action:Map.unmodifiable(other:var:);'), 48 | ]; 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /example/lib/grammar/math.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yangyiting 3 | * @Date: 2021-03-24 10:39:25 4 | * @Last Modified by: yangyiting 5 | * @Last Modified time: 2021-03-24 17:50:04 6 | * @Describe: math 7 | */ 8 | 9 | import 'package:flutter/material.dart'; 10 | import 'package:yz_flutter_dynamic/main.dart'; 11 | 12 | import 'base.dart'; 13 | 14 | class UTMath extends StatefulWidget { 15 | @override 16 | _UTMathState createState() => _UTMathState(); 17 | } 18 | 19 | class _UTMathState extends UTBaseState { 20 | 21 | String get getTitle => "Math"; 22 | 23 | List getItem() { 24 | return [ 25 | createItem("Math.sqrt", "var:=action:num(123);\n=action:Math.sqrt(value:var:);"), 26 | createItem("Math.exp", "var:=action:num(3);\n=action:Math.exp(value:var:);"), 27 | createItem("Math.log", "var:=action:num(123);\n=action:Math.log(value:var:);"), 28 | createItem("Math.min", "var:=action:num(228);\nvar:=action:num(188);\n=action:Math.min(value1:var:,value2:var:);"), 29 | createItem("Math.max", "var:=action:num(228);\nvar:=action:num(188);\n=action:Math.max(value1:var:,value2:var:);"), 30 | createItem("Math.pow", "var:=action:num(5);\nvar:=action:num(3);\n=action:Math.pow(value:var:,exponent:var:);"), 31 | createItem("Math.sin", "var:=action:num(228);\n=action:Math.sin(value:var:);"), 32 | createItem("Math.cos", "var:=action:num(228);\n=action:Math.cos(value:var:);"), 33 | createItem("Math.tan", "var:=action:num(228);\n=action:Math.tan(value:var:);"), 34 | createItem("Math.asin", "var:=action:num(0.5);\n=action:Math.asin(value:var:);"), 35 | createItem("Math.acos", "var:=action:num(0.5);\n=action:Math.acos(value:var:);"), 36 | createItem("Math.atan", "var:=action:num(0.5);\n=action:Math.atan(value:var:);"), 37 | createItem("Math.atan2", "var:=action:num(0.5);\nvar:=action:num(0.5);\n=action:Math.atan2(value1:var:,value2:var:);"), 38 | createItem("Math.e", "=action:Math.e()"), 39 | createItem("Math.ln10", "=action:Math.ln10()"), 40 | createItem("Math.ln2", "=action:Math.ln2()"), 41 | createItem("Math.log2e", "=action:Math.log2e()"), 42 | createItem("Math.log10e", "=action:Math.log10e()"), 43 | createItem("Math.pi", "=action:Math.pi()"), 44 | createItem("Math.sqrt1_2", "=action:Math.sqrt1_2()"), 45 | createItem("Math.sqrt2", "=action:Math.sqrt2()"), 46 | ]; 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /example/lib/grammar/number.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-12-01 11:20:04 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-12-02 14:49:05 6 | */ 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:yz_flutter_dynamic/main.dart'; 10 | 11 | import 'base.dart'; 12 | 13 | class UTNumber extends StatefulWidget { 14 | @override 15 | _UTNumberState createState() => _UTNumberState(); 16 | } 17 | 18 | class _UTNumberState extends UTBaseState { 19 | 20 | String get getTitle => "Number"; 21 | 22 | List getItem() { 23 | return [ 24 | createItem("int", "=action:int(123);"), 25 | createItem("double", "=action:double(123);"), 26 | createItem("num", "=action:num(123);"), 27 | createItem("num.+", "=action:num.+(1, 2);"), 28 | createItem("num.-", "=action:num.-(2, 1, 1);"), 29 | createItem("num./", "=action:num./(5, 2);"), 30 | createItem("num.%", "=action:num.%(5, 2);"), 31 | createItem("num.+=", "var:=num(5);\nvar:=num(2);\n=action:num.+=(ret:var:, opt:var:);\n"), 32 | createItem("num.-=", "var:=num(5);\nvar:=num(2);\n=action:num.-=(ret:var:, opt:var:);"), 33 | createItem("num.*=", "var:=num(5);\nvar:=num(2);\n=action:num.*=(ret:var:, opt:var:);"), 34 | createItem("num./=", "var:=num(5);\nvar:=num(2);\n=action:num./=(ret:var:, opt:var:);"), 35 | createItem("num.parse", "=action:num.parse(123);"), 36 | createItem("num.tryParse", "=action:num.tryParse(123);"), 37 | createItem("num.isInfinite", "=action:num.isInfinite(123);"), 38 | createItem("num.isFinite", "=action:num.isFinite(123);"), 39 | createItem("num.isNegative", "=action:num.isNegative(-123);"), 40 | createItem("num.abs", "=action:num.abs(-123);"), 41 | createItem("num.clamp", "=action:num.clamp(1, lowerLimit:2, upperLimit:3);"), 42 | createItem("num.ceil", "=action:num.ceil(1.5);"), 43 | createItem("num.ceilToDouble", "=action:num.ceilToDouble(1.5);"), 44 | createItem("num.compareTo", "=action:num.compareTo(1, 2);"), 45 | createItem("num.floor", "=action:num.floor(1.5);"), 46 | createItem("num.round", "=action:num.round(1.5);"), 47 | createItem("num.roundToDouble", "=action:num.roundToDouble(1.5);"), 48 | createItem("num.toDouble", "=action:num.toDouble(1);"), 49 | createItem("num.toInt", "=action:num.toInt(1.5);"), 50 | createItem("num.truncate", "=action:num.truncate(1.5);"), 51 | createItem("num.truncateToDouble", "=action:num.truncateToDouble(1.5);"), 52 | createItem("num.toString", "=action:num.toString(1.5);"), 53 | createItem("num.toStringAsExponential", "=action:num.toStringAsExponential(1.5);"), 54 | createItem("num.toStringAsFixed", "=action:num.toStringAsFixed(1.5, 2);"), 55 | createItem("num.toStringAsPrecision", "=action:num.toStringAsPrecision(1.5, 3);"), 56 | ]; 57 | } 58 | 59 | } -------------------------------------------------------------------------------- /example/lib/grammar/operators_lo.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-12-01 11:20:04 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-12-02 18:20:56 6 | */ 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:yz_flutter_dynamic/main.dart'; 10 | 11 | import 'base.dart'; 12 | 13 | class UTLogicalOperators extends StatefulWidget { 14 | @override 15 | _UTLogicalOperatorsState createState() => _UTLogicalOperatorsState(); 16 | } 17 | 18 | class _UTLogicalOperatorsState extends UTBaseState { 19 | 20 | String get getTitle => "Logical operators"; 21 | 22 | List getItem() { 23 | return [ 24 | createItem("Sys.!", 'var:=bool(false);\nvar:=action:Sys.!(var:);'), 25 | createItem("Sys.&&", 'var:=bool(true);var:=bool(true);var:=action:Sys.&&(var:,var:);'), 26 | createItem("Sys.||", 'var:=bool(true);var:=bool(false);var:=action:Sys.||(var:,var:);'), 27 | ]; 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /example/lib/grammar/operators_re.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-12-01 11:20:04 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-12-02 18:08:46 6 | */ 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:yz_flutter_dynamic/main.dart'; 10 | 11 | import 'base.dart'; 12 | 13 | class UTRelationalOperators extends StatefulWidget { 14 | @override 15 | _UTRelationalOperatorsState createState() => _UTRelationalOperatorsState(); 16 | } 17 | 18 | class _UTRelationalOperatorsState extends UTBaseState { 19 | 20 | String get getTitle => "Equality and relational operators"; 21 | 22 | List getItem() { 23 | return [ 24 | createItem("Sys.==", 'action:Sys.==(a,b);'), 25 | createItem("Sys.!=", 'action:Sys.!=(a,b);'), 26 | createItem("Sys.>", 'action:Sys.>(1,2);'), 27 | createItem("Sys.>=", 'action:Sys.>=(1,2);'), 28 | createItem("Sys.<", 'action:Sys.<(1,2);'), 29 | createItem("Sys.<=", 'action:Sys.<=(1,2);'), 30 | ]; 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /example/lib/grammar/set.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yangyiting 3 | * @Date: 2021-03-10 17:54:26 4 | * @Last Modified by: yangyiting 5 | * @Last Modified time: 2021-03-10 18:21:12 6 | */ 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:yz_flutter_dynamic/main.dart'; 10 | 11 | import 'base.dart'; 12 | 13 | class UTSet extends StatefulWidget { 14 | @override 15 | _UTSetState createState() => _UTSetState(); 16 | } 17 | 18 | class _UTSetState extends UTBaseState { 19 | 20 | String get getTitle => "Set"; 21 | 22 | List getItem() { 23 | return [ 24 | createItem("Set", "var:=action:Set(1,2,a,b);"), 25 | createItem("Set.contains", "var:=Set(aa,a,ab,bc);\nvar:=String(a);\nvar:=action:Set.contains(iterable:var:, element:var:)"), 26 | createItem("Set.add", "var:=Set(1,2,a,b);\naction:Set.add(target:var:, value:c);\nvar:=var:"), 27 | createItem("Set.addAll", "var:=Set(1,2,a,b);\nvar:=Set(c,d);\naction:Set.addAll(target:var:, value:));\nvar:=var:"), 28 | createItem("Set.remove", "var:=Set(1,2,a,b);\naction:Set.remove(target:var:, value:a);\nvar:=var:"), 29 | createItem("Set.lookup", "var:=Set(1,2,a,b);\nvar:=action:Set.lookup(target:var:,value:a)"), 30 | createItem("Set.removeAll", "var:=Set(1,2,a,b);\nvar:=Set(1,2);\naction:Set.removeAll(target:var:,value:var:);\nvar:=var:"), 31 | createItem("Set.retainAll", "var:=Set(1,2,a,b);\nvar:=Set(1,2);\naction:Set.retainAll(target:var:,value:var:);\nvar:=var:"), 32 | createItem("Set.containsAll", "var:=Set(1,2,a,b);\nvar:=Set(1,2);\nvar:=action:Set.containsAll(target:var:,value:var:);"), 33 | createItem("Set.intersection", "var:=Set(1,2,a,b);\nvar:=Set(1,2);\nvar:=action:Set.intersection(target:var:,value:var:);"), 34 | createItem("Set.union", "var:=Set(1,2,a,b);\nvar:=Set(1,2,c);\nvar:=action:Set.union(target:var:,value:var:);"), 35 | createItem("Set.difference", "var:=Set(1,2,a,b);\nvar:=Set(1,2,c);\nvar:=action:Set.difference(target:var:,value:var:);"), 36 | createItem("Set.clear", "var:=Set(1,2,a,b);\naction:Set.clear(target:var:);\nvar:=var:"), 37 | createItem("Set.toSet", "var:=Set(1,2,a,b);\nvar:=action:Set.toSet(iterable:var:);"), 38 | createItem("Set.toList", "var:=Set(1,2,a,b);\nvar:=action:Set.toList(iterable:var:);"), 39 | createItem("Set.elementAt", "var:=Set(a,b,c,d);\nvar:=action:Set.elementAt(iterable:var:,index:2);"), 40 | createItem("Set.length", "var:=Set(1,2,a,b);\nvar:=action:Set.length(iterable:var:));"), 41 | createItem("Set.isEmpty", "var:=Set(1,2,a,b);\nvar:=action:Set.isEmpty(iterable:var:));"), 42 | createItem("Set.isNotEmpty", "var:=Set(1,2,a,b);\nvar:=action:Set.isNotEmpty(iterable:var:));"), 43 | createItem("Set.first", "var:=Set(1,2,a,b);\nvar:=action:Set.first(iterable:var:));"), 44 | createItem("Set.last", "var:=Set(1,2,a,b);\nvar:=action:Set.last(iterable:var:));"), 45 | createItem("Set.followedBy", "var:=Set(1,2,3,4);\nvar:=Set(lala);var:=action:Set.followedBy(iterable:var:, other:var:);"), 46 | createItem("Set.join", "var:=Set(a,b,c,d);\nvar:=String(-);\nvar:=action:Set.join(iterable:var:,separator:var:)"), 47 | createItem("Set.take", "var:=Set(1,2,3,4);\nvar:=action:Set.take(iterable:var:,count:2);"), 48 | createItem("Set.skip", "var:=Set(1,2,3,4);\nvar:=action:Set.skip(iterable:var:,count:2);"), 49 | createItem("Set.toString", "var:=Set(a,b,c,d);\nvar:=action:Set.toString(iterable:var:);"), 50 | createItem("Set.iterator", "var:=Set(1,2,a,b);\nvar:=action:Set.iterator(target:var:));"), 51 | createItem("Set.from", "var:=Set(1,2,3,4);\nvar:=action:Set.from(elements:var:);"), 52 | createItem("Set.of", "var:=Set(1,2,3,4);\nvar:=action:Set.of(elements:var:);"), 53 | createItem("Set.identity", "var:=action:Set.identity();"), 54 | ]; 55 | } 56 | 57 | } -------------------------------------------------------------------------------- /example/lib/grammar/string.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-12-01 11:20:04 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-12-02 17:43:44 6 | */ 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:yz_flutter_dynamic/main.dart'; 10 | 11 | import 'base.dart'; 12 | 13 | class UTString extends StatefulWidget { 14 | @override 15 | _UTStringState createState() => _UTStringState(); 16 | } 17 | 18 | class _UTStringState extends UTBaseState { 19 | 20 | String get getTitle => "String"; 21 | 22 | List getItem() { 23 | return [ 24 | createItem("String", "=action:String(Hello world!);"), 25 | createItem("String.isEmpty", "=action:String.isEmpty(Hello world!);"), 26 | createItem("String.isNotEmpty", "=action:String.isNotEmpty(Hello world!);"), 27 | createItem("String.+", "=action:String.+(Hello, world, !);"), 28 | createItem("String.length", "=action:String.length(Hello world!);"), 29 | createItem("String.compareTo", "=action:String.compareTo(a,b);"), 30 | createItem("String.indexOf", "=action:String.indexOf(value:abc,pattern:b);"), 31 | createItem("String.lastIndexOf", "=action:String.lastIndexOf(value:abcbc,pattern:b);"), 32 | createItem("String.contains", "=action:String.contains(value:abc,other:b));"), 33 | createItem("String.endsWith", "=action:String.endsWith(value:abc,other:c));"), 34 | createItem("String.startsWith", "=action:String.startsWith(value:abc,other:c);"), 35 | createItem("String.padLeft", "=action:String.padLeft(value:abc, padding:c, width:5);"), 36 | createItem("String.padRight", "=action:String.padRight(value:abc,padding:c, width:5);"), 37 | createItem("String.replaceAll", "=action:String.replaceAll(value:acbc,from:c, replace:d);"), 38 | createItem("String.replaceFirst", "=action:String.replaceFirst(value:acbc,from:c, replace:d);"), 39 | createItem("String.replaceRange", "=action:String.replaceRange(value:acbc, start:1,end:3, replace:d);"), 40 | createItem("String.substring", "=action:String.substring(value:acbc, startIndex:1,endIndex:3);"), 41 | createItem("String.toLowerCase", "=action:String.toLowerCase(value:AbC);"), 42 | createItem("String.toUpperCase", "=action:String.toUpperCase(value:AbC);"), 43 | createItem("String.trim", "=action:String.trim(value: AbC );"), 44 | createItem("String.trimLeft", "=action:String.trimLeft(value: AbC );"), 45 | createItem("String.trimRight", "=action:String.trimRight(value: AbC );"), 46 | createItem("String.split", "=action:String.split(value:AbC, pattern:b);"), 47 | createItem("String.allMatches", "=action:String.allMatches(value:AbC,string:Ab);"), 48 | createItem("String.matchAsPrefix", "=action:String.matchAsPrefix(value:AbC,string:b);"), 49 | ]; 50 | } 51 | 52 | } -------------------------------------------------------------------------------- /example/lib/grammar/unittesting.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-12-01 11:09:56 4 | * @Last Modified by: yangyiting 5 | * @Last Modified time: 2021-03-24 17:47:18 6 | */ 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:yingzi_flutter_dynamicpage_example/grammar/bool.dart'; 10 | import 'package:yingzi_flutter_dynamicpage_example/grammar/math.dart'; 11 | import 'package:yingzi_flutter_dynamicpage_example/grammar/set.dart'; 12 | 13 | import 'controlflow.dart'; 14 | import 'list.dart'; 15 | import 'map.dart'; 16 | import 'number.dart'; 17 | import 'operators_lo.dart'; 18 | import 'operators_re.dart'; 19 | import 'string.dart'; 20 | import 'user_code.dart'; 21 | 22 | import 'package:yz_flutter_dynamic/main.dart'; 23 | 24 | class UnitTestingList extends StatefulWidget { 25 | @override 26 | _UnitTestingListState createState() => _UnitTestingListState(); 27 | } 28 | 29 | class _UnitTestingListState extends State { 30 | 31 | @override 32 | void initState() { 33 | super.initState(); 34 | } 35 | 36 | @override 37 | Widget build(BuildContext context) { 38 | return Scaffold( 39 | appBar: AppBar(title: Text('语法列表')), 40 | body: Padding( 41 | padding: EdgeInsets.all(10), 42 | child: SingleChildScrollView( 43 | child: Column( 44 | crossAxisAlignment: CrossAxisAlignment.start, 45 | children: [ 46 | createTitle('内建类型(Built-in types)'), 47 | createItem('Number', UTNumber()), 48 | createItem('String', UTString()), 49 | createItem('List', UTList()), 50 | createItem('Set', UTSet()), 51 | createItem('Map', UTMap()), 52 | createItem('bool', UTBool()), 53 | createItem('Math', UTMath()), 54 | createTitle('运算符(Operators)'), 55 | createItem('关系运算符(Equality and relational operators)', UTRelationalOperators()), 56 | createItem('逻辑运算符(Logical operators)', UTLogicalOperators()), 57 | createTitle('控制流程(Control flow statements)'), 58 | createItem('if and else', UTIfElse()), 59 | createItem('switch case', UTSwitchCase()), 60 | createItem('forloop', UTForloop()), 61 | createItem('while', UTWhile()), 62 | createTitle('User Code'), 63 | createItem('User Code', UTUserCode()), 64 | ], 65 | ), 66 | ) 67 | ), 68 | ); 69 | } 70 | 71 | Widget createTitle(String title) { 72 | return Container( 73 | child: Text(title, style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), 74 | margin: EdgeInsets.only(bottom: 10), 75 | ); 76 | } 77 | 78 | Widget createItem(String subTitle, Widget widget) { 79 | return Container( 80 | child: Column( 81 | crossAxisAlignment: CrossAxisAlignment.start, 82 | children: [ 83 | FlatButton( 84 | onPressed: (){ 85 | Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext contex){ 86 | return widget; 87 | })); 88 | }, 89 | child: Align(child: Text(subTitle, style: TextStyle(color: Colors.lightBlue)), alignment: Alignment.centerLeft) 90 | ), 91 | Divider() 92 | ], 93 | ), 94 | ); 95 | } 96 | 97 | } -------------------------------------------------------------------------------- /example/lib/grammar/user_code.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-12-25 11:22:29 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-12-25 11:22:29 6 | */ 7 | 8 | import 'package:yz_flutter_dynamic/main.dart'; 9 | import 'base.dart'; 10 | 11 | class YZUserCodeHandler extends YZDynamicUserActionHandler{ 12 | @override 13 | dynamic userCode(BuildContext context, { 14 | String userCode, 15 | Map localVariables, 16 | State state, 17 | }){ 18 | 19 | print(userCode); 20 | 21 | } 22 | } 23 | 24 | class UTUserCode extends StatefulWidget { 25 | @override 26 | _UTUserCodeState createState() => _UTUserCodeState(); 27 | } 28 | 29 | class _UTUserCodeState extends UTBaseState { 30 | 31 | String get getTitle => "User Code"; 32 | 33 | List getItem() { 34 | return [ 35 | createItem("User Code", 36 | '''userCode: 37 | var:=int(0); 38 | while (Sys.<=(, int(10))) { 39 | var:=num.+(, 1); 40 | }; 41 | var:=var:; 42 | action:String(var:) 43 | ''') 44 | ]; 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: yingzi_flutter_dynamicpage_example 2 | description: Demonstrates how to use the yz_flutter_dynamic plugin. 3 | publish_to: 'none' 4 | version: 0.0.1+1 5 | 6 | environment: 7 | sdk: ">=2.7.0 <3.0.0" 8 | 9 | dependencies: 10 | flutter: 11 | sdk: flutter 12 | 13 | # The following adds the Cupertino Icons font to your application. 14 | # Use with the CupertinoIcons class for iOS style icons. 15 | cupertino_icons: ^0.1.2 16 | fluttertoast: ^7.1.1 17 | 18 | dev_dependencies: 19 | flutter_test: 20 | sdk: flutter 21 | 22 | yz_flutter_dynamic: 23 | path: ../ 24 | 25 | # For information on the generic Dart part of this file, see the 26 | # following page: https://dart.dev/tools/pub/pubspec 27 | 28 | # The following section is specific to Flutter. 29 | flutter: 30 | 31 | # The following line ensures that the Material Icons font is 32 | # included with your application, so that you can use the icons in 33 | # the material Icons class. 34 | uses-material-design: true 35 | 36 | # To add assets to your application, add an assets section, like this: 37 | # assets: 38 | # - images/a_dot_burr.jpeg 39 | # - images/a_dot_ham.jpeg 40 | 41 | # An image asset can refer to one or more resolution-specific "variants", see 42 | # https://flutter.dev/assets-and-images/#resolution-aware. 43 | 44 | # For details regarding adding assets from package dependencies, see 45 | # https://flutter.dev/assets-and-images/#from-packages 46 | 47 | # To add custom fonts to your application, add a fonts section here, 48 | # in this "flutter" section. Each entry in this list should have a 49 | # "family" key with the font family name, and a "fonts" key with a 50 | # list giving the asset and other descriptors for the font. For 51 | # example: 52 | # fonts: 53 | # - family: Schyler 54 | # fonts: 55 | # - asset: fonts/Schyler-Regular.ttf 56 | # - asset: fonts/Schyler-Italic.ttf 57 | # style: italic 58 | # - family: Trajan Pro 59 | # fonts: 60 | # - asset: fonts/TrajanPro.ttf 61 | # - asset: fonts/TrajanPro_Bold.ttf 62 | # weight: 700 63 | # 64 | # For details regarding fonts from package dependencies, 65 | # see https://flutter.dev/custom-fonts/#from-packages 66 | -------------------------------------------------------------------------------- /example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:yingzi_flutter_dynamicpage_example/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Verify Platform version', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that platform version is retrieved. 19 | expect( 20 | find.byWidgetPredicate( 21 | (Widget widget) => widget is Text && 22 | widget.data.startsWith('Running on:'), 23 | ), 24 | findsOneWidget, 25 | ); 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-09-01 21:23:05 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-10-22 15:03:03 6 | **/ 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'tools/common.dart'; 10 | import 'pages/basic/page.dart'; 11 | import 'pages/builder.dart'; 12 | import 'pages/model/page_config.dart'; 13 | import 'pages/basic/utils.dart'; 14 | 15 | export 'package:flutter/material.dart'; 16 | export 'package:yz_flutter_dynamic/pages/basic/page.dart'; 17 | export 'package:yz_flutter_dynamic/tools/common.dart'; 18 | export 'package:yz_flutter_dynamic/tools/action.dart'; 19 | export 'package:yz_flutter_dynamic/tools/variable.dart'; 20 | export 'package:yz_flutter_dynamic/tools/network.dart'; 21 | export 'package:yz_flutter_dynamic/widgets/basic/handler.dart'; 22 | export 'package:yz_flutter_dynamic/widgets/basic/widget.dart'; 23 | export 'package:yz_flutter_dynamic/widgets/basic/data.dart'; 24 | export 'package:yz_flutter_dynamic/widgets/basic/utils.dart'; 25 | 26 | /// 入口类(Entry class) 27 | /// 注意事项:YZDynamic接收的dsl Map类型中的value需要转换成dynamic,而不是通过type infer成为其它类型的,可通过jsonEncode/jsonDecode方法强制转换 28 | /// Note: The value in the dsl Map type received by YZDynamic needs to be converted to dynamic instead of other types through type infer. It can be forced to be converted through the jsonEncode/jsonDecode method 29 | class YZDynamic { 30 | YZDynamic._(); 31 | 32 | // deprecated public 33 | static Widget buildPage(BuildContext context, Map config, 34 | {YZDynamicPagePreConfig? preConfig}) { 35 | Widget widget; 36 | 37 | //You shoud register widgets first or it wouldn't create widget 38 | YZDynamicCommon.registerSysWidgets(); 39 | //You shoud register sys public action first or it wouldn't be found 40 | YZDynamicCommon.registerSysPublicActionHandlers(); 41 | 42 | widget = YZDynamicPageTemplateBuilder.build(context, config, 43 | preConfig: preConfig); 44 | 45 | return widget; 46 | } 47 | 48 | // public 49 | static Widget buildWidget(BuildContext context, Map config, 50 | {YZDynamicPagePreConfig? preConfig}) { 51 | Widget widget; 52 | 53 | Map json; 54 | if (config['page'] == null || config['isOldVersion'] != null) { 55 | json = { 56 | "type": "custompage", 57 | "page": {"rootWidget": config.cast()} 58 | }; 59 | } else { 60 | json = config; 61 | } 62 | 63 | widget = YZDynamic.buildPage(context, json, preConfig: preConfig); 64 | 65 | return widget; 66 | } 67 | 68 | // public 69 | // 相比buildPage, handle还支持处理页面的呈现方式 70 | // Compared to buildPage, The method of handle also supports processing the presentation of page. 71 | static handle(BuildContext context, Map? dsl, 72 | {YZDynamicPagePreConfig? preConfig, 73 | Function(dynamic returnResult)? routerPopCallBack}) { 74 | assert(dsl != null, 'Error: Dsl can not be null!'); 75 | if (dsl == null || dsl.isEmpty) { 76 | return null; 77 | } 78 | 79 | Map config = dsl; 80 | 81 | Map _pageConfig = config['page']; 82 | YZDynamicPageTemplateConfig _pageConfigObj = 83 | YZDynamicPageTemplateConfig.fromJson(_pageConfig); 84 | String? _presentMode = _pageConfigObj.presentMode; 85 | 86 | YZDinamicPageMode _mode = YZDinamicPageUtils.pageMode(_presentMode); 87 | switch (_mode) { 88 | case YZDinamicPageMode.dialog: 89 | () async { 90 | await showDialog( 91 | context: context, 92 | builder: (BuildContext context) { 93 | Widget child = 94 | YZDynamic.buildPage(context, config, preConfig: preConfig); 95 | return Dialog(child: child); 96 | }); 97 | }(); 98 | break; 99 | default: 100 | { 101 | Future futureResultCallBack = Navigator.of(context) 102 | .push(MaterialPageRoute(builder: (BuildContext contex) { 103 | return YZDynamic.buildPage(context, config, preConfig: preConfig); 104 | })); 105 | if (null != routerPopCallBack) { 106 | futureResultCallBack.then(routerPopCallBack); 107 | } 108 | } 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /lib/pages/basic/lifecycle.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-09-23 16:52:49 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-09-23 17:00:56 6 | */ 7 | 8 | /// 9 | /// 管理页面的生命周期,用类似事件的方式对应生命周期的不同阶段,并关联配置的action 10 | /// Manager page state 11 | /// The state's every stage is similar the event that relative to the action configed 12 | /// 13 | 14 | -------------------------------------------------------------------------------- /lib/pages/basic/utils.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-09-14 21:37:16 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2021-01-27 14:59:17 6 | **/ 7 | 8 | import 'dart:ui'; 9 | 10 | class YZDinamicPageUtils { 11 | 12 | static pageMode(String? pagetMode) { 13 | switch (pagetMode) { 14 | case 'dialog': 15 | return YZDinamicPageMode.dialog; 16 | default: 17 | return YZDinamicPageMode.navpage; 18 | } 19 | } 20 | 21 | ///adapt dsl color to the flutter color 0xff123456 22 | static Color? colorAdapter(String? colorString){ 23 | Color? color; 24 | if (colorString != null) { 25 | int? v = int.tryParse(colorString); 26 | color = v != null ? Color(v) : null; 27 | } 28 | 29 | return color; 30 | } 31 | 32 | } 33 | 34 | enum YZDinamicPageMode { 35 | dialog, 36 | navpage, 37 | } -------------------------------------------------------------------------------- /lib/pages/builder.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-09-01 22:06:01 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-11-03 14:24:37 6 | **/ 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'basic/page.dart'; 10 | import 'custompage.dart'; 11 | import 'formpage.dart'; 12 | import 'formwidget.dart'; 13 | import 'model/page_config.dart'; 14 | 15 | class YZDynamicPageTemplateBuilder { 16 | YZDynamicPageTemplateBuilder._(); 17 | 18 | static Widget build(BuildContext context, Map config, {YZDynamicPagePreConfig? preConfig}) { 19 | Widget page; 20 | 21 | Map _pageConfig = config['page']; 22 | YZDynamicPageTemplateConfig _pageConfigObj = YZDynamicPageTemplateConfig.fromJson(_pageConfig); 23 | String? _pageType = _pageConfigObj.type; 24 | 25 | if (_pageType == 'formpage') { 26 | print("-->>>formpage: ${_pageConfigObj.name}"); 27 | Map _submitJson = config['submit']; 28 | Map _navbarJson = config['navbar']; 29 | List _children = List.castFrom(config['children']); 30 | page = YZDynamicFormPage( 31 | _children, 32 | submitJson: _submitJson, 33 | pageConfig: _pageConfigObj, 34 | preConfig: preConfig, 35 | navbarJson: _navbarJson 36 | ); 37 | } else { 38 | 39 | ///从设计器来的数据模型采用formpage的方式返回wigget的类型,子元素存在children中 40 | if (_pageConfigObj.rootWidget == null || _pageConfigObj.rootWidget!.isEmpty) { 41 | print("==>>>formwidget: ${_pageConfigObj.name}"); 42 | List _children = List.castFrom(config['children']); 43 | page = YZDynamicFormWidget( 44 | _children, 45 | pageConfig: _pageConfigObj, 46 | preConfig: preConfig, 47 | ); 48 | } else { 49 | print("~~>>>custompage: ${_pageConfigObj.name}"); 50 | page = YZDynamicCustomPage( 51 | _pageConfigObj, 52 | preConfig: preConfig, 53 | ); 54 | } 55 | } 56 | 57 | return page; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /lib/pages/custompage.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-09-01 21:36:18 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-11-03 14:52:59 6 | **/ 7 | 8 | import 'package:flutter/material.dart'; 9 | import '../tools/common.dart'; 10 | import 'basic/page.dart'; 11 | import 'model/page_config.dart'; 12 | 13 | /// 用户自定义页面 14 | /// User customize page 15 | class YZDynamicCustomPage extends YZDynamicBasePage { 16 | final YZDynamicPageTemplateConfig? pageConfig; 17 | final YZDynamicPagePreConfig? preConfig; 18 | 19 | YZDynamicCustomPage(this.pageConfig, {this.preConfig}) 20 | : super(pageConfig: pageConfig, preConfig: preConfig); 21 | 22 | @override 23 | _YZDynamicCustomPageState createState() => _YZDynamicCustomPageState(); 24 | } 25 | 26 | class _YZDynamicCustomPageState 27 | extends YZDynamicBaseState { 28 | Map? _rootWidgetJson; 29 | 30 | @override 31 | void initState() { 32 | super.initState(); 33 | 34 | _rootWidgetJson = widget.pageConfig?.rootWidget; 35 | if (_rootWidgetJson != null && 36 | _rootWidgetJson!['widgetName'] == 'Scaffold') { 37 | Map? props = _rootWidgetJson!['props']; 38 | if (props != null) { 39 | Map appBar = props['appBar']; 40 | dealWidgetKey(appBar); 41 | Map body = props['body']; 42 | dealWidgetKey(body); 43 | } 44 | } else { 45 | dealWidgetKey(_rootWidgetJson); 46 | } 47 | } 48 | 49 | @override 50 | void registerActions() { 51 | super.registerActions(); 52 | } 53 | 54 | @override 55 | Widget build(BuildContext context) { 56 | super.build(context); 57 | 58 | Widget? _rootWidget = 59 | YZDynamicCommon.buildWidget(_rootWidgetJson, context: context); 60 | 61 | assert(_rootWidget != null, 'Error: rootWidget can not be null! Do you mean formwidget?'); 62 | if (_rootWidget == null) return Text('rootWidget is null! Do you specify custompage?'); 63 | 64 | return Container( 65 | key: UniqueKey(), 66 | child: _rootWidget, 67 | ); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /lib/pages/formpage.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-09-01 21:36:18 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2021-01-27 14:59:37 6 | **/ 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:yz_flutter_dynamic/widgets/form.dart'; 10 | 11 | import '../tools/common.dart'; 12 | import 'basic/page.dart'; 13 | import 'basic/utils.dart'; 14 | import 'model/page_config.dart'; 15 | 16 | ///One-Dimension Column Form Layout (单列表单布局) 17 | class YZDynamicFormPage extends YZDynamicBasePage { 18 | final YZDynamicPageTemplateConfig? pageConfig; 19 | final Map? navbarJson; 20 | final Map? submitJson; 21 | final List? childrenJson; 22 | final YZDynamicPagePreConfig? preConfig; 23 | 24 | YZDynamicFormPage(this.childrenJson, 25 | {this.pageConfig, this.navbarJson, this.submitJson, this.preConfig}) 26 | : super(pageConfig: pageConfig, preConfig: preConfig); 27 | 28 | @override 29 | _YZDynamicFormPageState createState() => _YZDynamicFormPageState(); 30 | } 31 | 32 | class _YZDynamicFormPageState extends YZDynamicBaseState { 33 | @override 34 | void initState() { 35 | super.initState(); 36 | 37 | assert(widget.childrenJson != null, 38 | 'The children should not be null for formpage type.'); 39 | for (Map json in widget.childrenJson!) { 40 | dealWidgetKey(json); 41 | } 42 | dealWidgetKey(widget.navbarJson); 43 | dealWidgetKey(widget.submitJson); 44 | } 45 | 46 | @override 47 | void registerActions() { 48 | super.registerActions(); 49 | } 50 | 51 | @override 52 | Widget build(BuildContext context) { 53 | super.build(context); 54 | List? children = []; 55 | for (Map json in widget.childrenJson!) { 56 | String xKey = json['xKey']; 57 | Widget? widget = YZDynamicCommon.buildWidget(json, context: context); 58 | if ((widget is Column) || (widget is PreferredSizeWidget)) { 59 | print('Error: Form widget can not be Column or PreferredSizeWidget'); 60 | continue; 61 | } 62 | if (widget == null) { 63 | String widgetName = json['widgetName']; 64 | children.add(Text('Not found widget of "$widgetName" for xKey "$xKey"')); 65 | } else { 66 | children.add(widget); 67 | } 68 | } 69 | 70 | if (children.isEmpty) { 71 | children = [Text('No widgets')]; 72 | } 73 | 74 | Widget? navbar = 75 | YZDynamicCommon.buildWidget(widget.navbarJson, context: context); 76 | if (navbar == null || navbar is! AppBar) { 77 | navbar = AppBar(title: Text('Dynamic form page')); 78 | } 79 | 80 | Widget? submit = 81 | YZDynamicCommon.buildWidget(widget.submitJson, context: context); 82 | if (submit == null) { 83 | submit = Container(); 84 | } 85 | 86 | EdgeInsets? _padding = 87 | YZDynamicCommon.edgeInsetAdapter(super.pageConfig?.props?.padding) ?? 88 | EdgeInsets.zero; 89 | Color? _backgroundColor = YZDinamicPageUtils.colorAdapter( 90 | super.pageConfig?.props?.backgroundColor) ?? 91 | Color(0xFFFFFFFF); 92 | return Scaffold( 93 | backgroundColor: _backgroundColor, 94 | appBar: navbar, 95 | body: SafeArea( 96 | child: Padding( 97 | padding: _padding, 98 | child: YZForm( 99 | child: Column( 100 | children: [ 101 | Expanded( 102 | child: SingleChildScrollView( 103 | child: Column( 104 | children: children, 105 | ), 106 | )), 107 | submit, 108 | ], 109 | )), 110 | )), 111 | ); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /lib/pages/formwidget.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-09-01 21:36:18 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2021-01-27 14:59:37 6 | **/ 7 | 8 | import 'package:flutter/material.dart'; 9 | 10 | import '../tools/common.dart'; 11 | import 'basic/page.dart'; 12 | import 'model/page_config.dart'; 13 | 14 | /// 应用了表单 (formpage )数据模型的Widget,不包含nav和submit 15 | class YZDynamicFormWidget extends YZDynamicBasePage { 16 | final YZDynamicPageTemplateConfig? pageConfig; 17 | final List? childrenJson; 18 | final YZDynamicPagePreConfig? preConfig; 19 | 20 | YZDynamicFormWidget(this.childrenJson, 21 | {this.pageConfig, this.preConfig}) 22 | : super(pageConfig: pageConfig, preConfig: preConfig); 23 | 24 | @override 25 | _YZDynamicFormWidgetState createState() => _YZDynamicFormWidgetState(); 26 | } 27 | 28 | class _YZDynamicFormWidgetState extends YZDynamicBaseState { 29 | @override 30 | void initState() { 31 | super.initState(); 32 | 33 | assert(widget.childrenJson != null, 34 | 'The children should not be null for formpage type.'); 35 | // for (Map json in widget.childrenJson) { 36 | // dealWidgetKey(json); 37 | // } 38 | } 39 | 40 | @override 41 | void registerActions() { 42 | super.registerActions(); 43 | } 44 | 45 | @override 46 | Widget build(BuildContext context) { 47 | super.build(context); 48 | if (widget.childrenJson?.length == 1) { 49 | return YZDynamicCommon.buildWidget(widget.childrenJson![0], context: context)!; 50 | } else { 51 | List children = []; 52 | for (Map json in widget.childrenJson!) { 53 | String xKey = json['xKey']; 54 | Widget? widget = YZDynamicCommon.buildWidget(json, context: context); 55 | if ((widget is Column) || (widget is PreferredSizeWidget)) { 56 | print('Error: Form widget can not be Column or PreferredSizeWidget'); 57 | continue; 58 | } 59 | if (widget == null) { 60 | String widgetName = json['widgetName']; 61 | children.add(Text('Not found widget of "$widgetName" for xKey "$xKey"')); 62 | } else { 63 | children.add(widget); 64 | } 65 | } 66 | 67 | if (children.isEmpty) { 68 | children = [Text('No widgets')]; 69 | } 70 | 71 | return Column(children: children); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /lib/pages/model/page_config.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-09-02 10:48:50 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2021-01-27 14:57:17 6 | **/ 7 | 8 | import 'dart:convert'; 9 | 10 | import '../../tools/action.dart'; 11 | export '../../tools/action.dart'; 12 | 13 | class YZDynamicPageTemplateConfig { 14 | String? key; 15 | String? type; 16 | String? name; 17 | String? presentMode; 18 | String? routeTag; 19 | YZDynamicPageProps? props; 20 | YZDynamicPageLifecycle? state; 21 | Map? xActions; 22 | Map? rootWidget; 23 | Map? xVar; 24 | 25 | YZDynamicPageTemplateConfig( 26 | {this.key, 27 | this.type, 28 | this.name, 29 | this.presentMode, 30 | this.routeTag, 31 | this.props, 32 | this.state, 33 | this.xActions, 34 | this.rootWidget, 35 | this.xVar}); 36 | 37 | YZDynamicPageTemplateConfig.fromJson(Map json) { 38 | key = json['key']; 39 | type = json['type']; 40 | name = json['name']; 41 | presentMode = json['presentMode']; 42 | routeTag = json['routeTag']; 43 | props = json['props'] != null ? new YZDynamicPageProps.fromJson(json['props']) : null; 44 | state = json['state'] != null 45 | ? new YZDynamicPageLifecycle.fromJson(json['state']) 46 | : null; 47 | if (json['xActions'] != null) { 48 | xActions = (json['xActions'] as Map).map( 49 | (key, value) => MapEntry(key, YZDynamicActionConfig.fromJson(value)) 50 | ); 51 | } 52 | rootWidget = json['rootWidget']; 53 | xVar = json['xVar']; 54 | } 55 | 56 | } 57 | 58 | class YZDynamicPageProps { 59 | List? padding; 60 | String? backgroundColor; 61 | 62 | YZDynamicPageProps({this.padding, this.backgroundColor}); 63 | 64 | YZDynamicPageProps.fromJson(Map json) { 65 | padding = json['padding'] == null ? null : jsonDecode(json['padding']); 66 | backgroundColor = json['backgroundColor']; 67 | } 68 | 69 | } 70 | 71 | class YZDynamicPageLifecycle { 72 | List? beforeEntrance; 73 | List? initState; 74 | List? build; 75 | List? dispose; 76 | List? afterLeave; 77 | 78 | YZDynamicPageLifecycle( 79 | {this.beforeEntrance, 80 | this.initState, 81 | this.build, 82 | this.dispose, 83 | this.afterLeave}); 84 | 85 | YZDynamicPageLifecycle.fromJson(Map json) { 86 | if (json['beforeEntrance'] != null) { 87 | beforeEntrance = []; 88 | json['beforeEntrance'].forEach((v) { 89 | beforeEntrance!.add(new YZDynamicActionConfig.fromJson(v)); 90 | }); 91 | } 92 | if (json['initState'] != null) { 93 | initState = []; 94 | json['initState'].forEach((v) { 95 | initState!.add(new YZDynamicActionConfig.fromJson(v)); 96 | }); 97 | } 98 | if (json['build'] != null) { 99 | build = []; 100 | json['build'].forEach((v) { 101 | build!.add(new YZDynamicActionConfig.fromJson(v)); 102 | }); 103 | } 104 | if (json['dispose'] != null) { 105 | dispose = []; 106 | json['dispose'].forEach((v) { 107 | dispose!.add(new YZDynamicActionConfig.fromJson(v)); 108 | }); 109 | } 110 | if (json['afterLeave'] != null) { 111 | afterLeave = []; 112 | json['afterLeave'].forEach((v) { 113 | afterLeave!.add(new YZDynamicActionConfig.fromJson(v)); 114 | }); 115 | } 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /lib/tools/actions/regexp.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-10-29 12:05:18 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-10-29 12:05:18 6 | */ 7 | 8 | part of '../action.dart'; 9 | 10 | class YZRegExpHasMatchHandler extends YZDynamicSysActionHandler{ 11 | @override 12 | dynamic func(Map? params) { 13 | if (params == null) return false; 14 | 15 | String? pattern = params['pattern']; 16 | if (pattern == null) return false; 17 | 18 | String? value = params['value']; 19 | if (value == null) return false; 20 | 21 | RegExp regExp = RegExp(pattern); 22 | bool isMatch = regExp.hasMatch(value); 23 | return isMatch; 24 | } 25 | 26 | @override 27 | String get actionName => 'RegExp.hasMatch'; 28 | 29 | } -------------------------------------------------------------------------------- /lib/tools/actions/router.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-10-29 12:04:22 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-10-29 12:04:22 6 | */ 7 | 8 | part of '../action.dart'; 9 | 10 | class YZRouterPopHandler extends YZDynamicPublicActionHandler{ 11 | @override 12 | void action(BuildContext? context, { 13 | Map? params, 14 | YZDynamicRequest? request, 15 | List? rules, 16 | Map? localVariables, 17 | State? state, 18 | }) { 19 | print('xAction: YZPagePopHandler Router.pop'); 20 | 21 | if (context == null) return; 22 | Navigator.of(context).pop(); 23 | } 24 | 25 | @override 26 | String get actionName => 'Router.pop'; 27 | 28 | } -------------------------------------------------------------------------------- /lib/tools/network.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-09-27 22:44:28 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-10-28 14:37:22 6 | */ 7 | 8 | import 'action.dart'; 9 | import 'common.dart'; 10 | 11 | class YZDynamicRequest { 12 | String? url; 13 | String? method; 14 | Map? params; 15 | Map? header; 16 | YZDynamicRequestResult? succeed; 17 | YZDynamicRequestResult? failed; 18 | String? responseDataVar; //返回数据的存放变量,The storage variable of response data 19 | 20 | YZDynamicRequest( 21 | {this.url, this.method, this.params, this.responseDataVar, this.header}); 22 | 23 | YZDynamicRequest.fromJson(Map? json) { 24 | if (json == null) return; 25 | url = json['url']; 26 | method = json['method']; 27 | params = YZDynamicCommon.dynamicToMap(json['params']); 28 | header = YZDynamicCommon.dynamicToMap(json['header']); 29 | succeed = json['succeed'] == null 30 | ? null 31 | : YZDynamicRequestResult.fromJson(json['succeed']); 32 | failed = json['failed'] == null 33 | ? null 34 | : YZDynamicRequestResult.fromJson(json['failed']); 35 | responseDataVar = json['responseDataVar']; 36 | } 37 | } 38 | 39 | class YZDynamicRequestResult { 40 | List? actions; 41 | String? tip; 42 | Map? params; 43 | 44 | YZDynamicRequestResult({this.actions, this.tip, this.params}); 45 | 46 | YZDynamicRequestResult.fromJson(Map json) { 47 | if (json['actions'] != null) { 48 | actions = (json['actions'] as List) 49 | .map((e) => YZDynamicActionConfig.fromJson(e)) 50 | .toList(); 51 | } 52 | tip = json['tip']; 53 | params = json['params']; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /lib/tools/rule.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-10-28 14:08:10 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-10-28 23:23:42 6 | */ 7 | 8 | import 'package:flutter/material.dart'; 9 | import '../pages/basic/page.dart'; 10 | import 'code.dart'; 11 | import 'variable.dart'; 12 | import 'network.dart'; 13 | 14 | const _YZDynamicRuleTag = 'rule:'; 15 | 16 | class YZDynamicRuleUtil { 17 | 18 | YZDynamicRuleUtil._(); 19 | 20 | /// 支持简写格式(code):rule:targetKey|reg|tip->returnVariable| 21 | /// Support simple format(code): rule:targetKey|reg|tip->returnVariable| 22 | static bool validate( 23 | List? rules, 24 | { 25 | String? value, 26 | State? state, 27 | Function(int?, String?)? callback 28 | } 29 | ) { 30 | 31 | if (rules != null && (rules is List)) { 32 | for (var i = 0; i < rules.length; i++) { 33 | var rule = rules[i]; 34 | if (rule?.reg == null) return true; 35 | 36 | //临时方案,简写放在reg字段里了 37 | if (rule!.reg!.startsWith(_YZDynamicRuleTag)) { 38 | rule = anylizeCodeRule(rule.reg); 39 | } else if (YZDynamicCodeUtil.isCode(rule.reg)) { 40 | bool ret = YZDynamicCodeUtil.execute(rule.reg, state: state); 41 | if (!ret) { 42 | return false; 43 | } else { 44 | continue; 45 | } 46 | } 47 | 48 | if (rule!.targetKey != null && rule.targetKey!.isNotEmpty) { 49 | assert(state != null, "Error: context con't be null"); 50 | if (state != null) { 51 | value = YZDynamicBasePage.getVariable(state.context, rule.targetKey, type:YZDynamicVariableType.widget); 52 | } 53 | } 54 | 55 | RegExp regExp = RegExp(rule.reg!); 56 | bool isMatch = regExp.hasMatch(value??''); 57 | if (isMatch != true) { 58 | if (callback != null) { 59 | callback(i, rule.tip); 60 | } 61 | return false; 62 | } 63 | } 64 | } 65 | 66 | return true; 67 | } 68 | 69 | static YZDynamicActionRule? anylizeCodeRule(String? codeRule, {State? state, Map? localVariables}) { 70 | 71 | if (codeRule == null) return null; 72 | 73 | codeRule = codeRule.replaceAll(RegExp(r"\s"), ''); 74 | if (codeRule.length <= _YZDynamicRuleTag.length) return null; 75 | 76 | String ruleStrRaw= codeRule.substring(_YZDynamicRuleTag.length); 77 | YZDynamicActionRule rule = YZDynamicActionRule(); 78 | 79 | List regArr = ruleStrRaw.split('|'); 80 | if (regArr.length >= 4) { 81 | rule.targetKey = regArr[0]; 82 | rule.reg = regArr[1]; 83 | rule.tip = regArr[2]; 84 | rule.returnVariable = regArr[3]; 85 | } else if (regArr.length >= 3) { 86 | rule.targetKey = regArr[0]; 87 | rule.reg = regArr[1]; 88 | rule.tip = regArr[2]; 89 | } else if (regArr.length >= 2){ 90 | rule.targetKey = regArr[0]; 91 | rule.reg = regArr[1]; 92 | } 93 | 94 | return rule; 95 | } 96 | 97 | } 98 | 99 | class YZDynamicActionRule { 100 | String? targetKey; 101 | String? name; 102 | String? reg; 103 | String? tip; 104 | YZDynamicRequest? request; 105 | String? code; 106 | String? returnVariable; 107 | 108 | YZDynamicActionRule({this.targetKey, this.name, this.reg, this.tip, this.request, this.code, this.returnVariable}); 109 | 110 | YZDynamicActionRule.fromJson(Map json) { 111 | targetKey = json['targetKey']; 112 | name = json['name']; 113 | reg = json['reg']; 114 | tip = json['tip']; 115 | request = json['request'] != null ? new YZDynamicRequest.fromJson(json['request']) : null; 116 | code = json['code']; 117 | returnVariable = json['returnVariable']; 118 | } 119 | 120 | } -------------------------------------------------------------------------------- /lib/widgets/alert_dialog.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-11-13 08:48:47 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-11-13 08:48:47 6 | */ -------------------------------------------------------------------------------- /lib/widgets/align.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Align 3 | * @Author: chenlijiao 4 | * @Date: 2021-03-16 15:02:31 5 | * @LastEditors: chenlijiao 6 | * @LastEditTime: 2021-03-16 16:49:06 7 | */ 8 | 9 | import 'package:flutter/material.dart'; 10 | import 'package:yz_flutter_dynamic/tools/common.dart'; 11 | import 'basic/handler.dart'; 12 | import 'basic/utils.dart'; 13 | import 'basic/widget.dart'; 14 | 15 | class YZAlignHandler extends YZDynamicBasicWidgetHandler { 16 | @override 17 | String get widgetName => 'Align'; 18 | 19 | @override 20 | Widget build(Map json, 21 | {Key? key, BuildContext? buildContext}) { 22 | return _Builder(json, key: key); 23 | } 24 | } 25 | 26 | class _Builder extends YZDynamicBaseWidget { 27 | final Map json; 28 | 29 | _Builder(this.json, {Key? key}) : super(json, key: key); 30 | 31 | @override 32 | _BuilderState createState() => _BuilderState(); 33 | } 34 | 35 | class _BuilderState extends YZDynamicWidgetBasicState<_Builder> { 36 | //Deal with props / 处理控件属性 37 | late YZAlignConfig props; 38 | AlignmentGeometry? _alignment; 39 | double? _widthFactor; 40 | double? _heightFactor; 41 | Widget? _child; 42 | 43 | @override 44 | void initState() { 45 | super.initState(); 46 | 47 | //Deal with props / 处理控件属性 48 | props = YZAlignConfig.fromJson(super.config?.props ?? {}); 49 | _alignment = YZDynamicWidgetUtils.alignmentAdapter(props.alignment); 50 | _widthFactor = YZDynamicWidgetUtils.doubleAdapter(props.widthFactor); 51 | _heightFactor = YZDynamicWidgetUtils.doubleAdapter(props.heightFactor); 52 | _child = props.child == null 53 | ? null 54 | : YZDynamicCommon.buildWidget(props.child, context: context); 55 | } 56 | 57 | @override 58 | Widget build(BuildContext context) { 59 | Widget _widget; 60 | 61 | Align _subwidget = Align( 62 | alignment: _alignment ?? Alignment.center, 63 | widthFactor: _widthFactor, 64 | heightFactor: _heightFactor, 65 | child: _child, 66 | ); 67 | 68 | //Deal with events / 处理事件 69 | _widget = super.buildWithEvents(_subwidget, super.config?.xEvents); 70 | 71 | return _widget; 72 | } 73 | 74 | @override 75 | void registerActions() { 76 | //Deal with action / 处理事件实现 77 | } 78 | 79 | } 80 | 81 | /// The props of Align config 82 | class YZAlignConfig { 83 | String? alignment; 84 | String? widthFactor; 85 | String? heightFactor; 86 | Map? child; 87 | 88 | YZAlignConfig( 89 | {this.alignment, this.heightFactor, this.widthFactor, this.child}); 90 | 91 | YZAlignConfig.fromJson(Map? json) { 92 | json ??= {}; 93 | alignment = json['alignment']; 94 | widthFactor = json['widthFactor']; 95 | heightFactor = json['heightFactor']; 96 | child = json['child']; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /lib/widgets/all.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-09-13 22:53:58 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-11-26 18:11:40 6 | **/ 7 | 8 | import 'package:yz_flutter_dynamic/widgets/align.dart'; 9 | import 'package:yz_flutter_dynamic/widgets/center.dart'; 10 | import 'package:yz_flutter_dynamic/widgets/checkbox.dart'; 11 | import 'package:yz_flutter_dynamic/widgets/clip_rrect.dart'; 12 | import 'package:yz_flutter_dynamic/widgets/flexible.dart'; 13 | import 'package:yz_flutter_dynamic/widgets/gesture_detector.dart'; 14 | import 'package:yz_flutter_dynamic/widgets/listView.dart'; 15 | import 'package:yz_flutter_dynamic/widgets/offstage.dart'; 16 | import 'package:yz_flutter_dynamic/widgets/positioned.dart'; 17 | import 'package:yz_flutter_dynamic/widgets/radio.dart'; 18 | import 'package:yz_flutter_dynamic/widgets/stack.dart'; 19 | import 'package:yz_flutter_dynamic/widgets/wrap.dart'; 20 | import 'statefulwidget.dart'; 21 | import 'statelesswidget.dart'; 22 | import 'app_bar.dart'; 23 | import 'basic.dart'; 24 | import 'basic/handler.dart'; 25 | import 'button.dart'; 26 | import 'column.dart'; 27 | import 'container.dart'; 28 | import 'dialog.dart'; 29 | import 'expanded.dart'; 30 | import 'image.dart'; 31 | import 'padding.dart'; 32 | import 'row.dart'; 33 | import 'safe_area.dart'; 34 | import 'scaffold.dart'; 35 | import 'scroll_view.dart'; 36 | import 'text.dart'; 37 | import 'text_field.dart'; 38 | import 'divider.dart'; 39 | 40 | /// All handlers for register 41 | List yzAllDynamicWidgetHandlers = [ 42 | YZContainerHandler(), 43 | YZTextHandler(), 44 | YZTextFieldHandler(), 45 | YZColumnHandler(), 46 | YZExpandedHandler(), 47 | YZImageHandler(), 48 | YZPaddingHandler(), 49 | YZRowHandler(), 50 | YZSafeAreaHandler(), 51 | YZSingleChildScrollViewHandler(), 52 | YZScaffoldHandler(), 53 | YZAppBarHandler(), 54 | YZRawMaterialButtonHandler(), 55 | YZSizedBoxHandler(), 56 | YZDialogHandler(), 57 | YZStatefulWidgetHandler(), 58 | YZStatelessWidgetHandler(), 59 | YZDividerHandler(), 60 | YZFlexibleHandler(), 61 | YZPositionedHandler(), 62 | YZStackHandler(), 63 | YZWrapHandler(), 64 | YZAlignHandler(), 65 | YZCenterHandler(), 66 | YZOffstageHandler(), 67 | YZListViewHandler(), 68 | YZCheckboxHandler(), 69 | YZRadioHandler(), 70 | YZGestureDetectorHandler(), 71 | YZClipRRectHandler() 72 | ]; 73 | -------------------------------------------------------------------------------- /lib/widgets/basic.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-11-19 09:40:11 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-11-19 10:08:05 6 | */ 7 | 8 | import 'package:flutter/material.dart'; 9 | import '../tools/common.dart'; 10 | 11 | import 'basic/handler.dart'; 12 | import 'basic/utils.dart'; 13 | import 'model/widget_config.dart'; 14 | 15 | /// SizedBox handler 16 | class YZSizedBoxHandler extends YZDynamicBasicWidgetHandler { 17 | 18 | @override 19 | String get widgetName => 'SizedBox'; 20 | 21 | @override 22 | Widget build(Map json, {Key? key, BuildContext? buildContext}) { 23 | 24 | //Deal with props / 处理控件属性 25 | YZDynamicWidgetConfig config = YZDynamicWidgetConfig.fromJson(json); 26 | YZSizedBoxConfig props = YZSizedBoxConfig.fromJson(config.props ?? {}); 27 | String? _type = props.type; 28 | Widget? _child = props.child == null ? null : YZDynamicCommon.buildWidget(props.child, context: buildContext); 29 | 30 | SizedBox _widget; 31 | switch (_type) { 32 | case 'expand': 33 | _widget = SizedBox.expand( 34 | child: _child 35 | ); 36 | break; 37 | case 'shrink': 38 | _widget = SizedBox.shrink( 39 | child: _child 40 | ); 41 | break; 42 | case 'fromSize': 43 | Size? _size = YZDynamicWidgetUtils.sizeAdapter(props.size); 44 | _widget = SizedBox.fromSize( 45 | size: _size, 46 | child: _child 47 | ); 48 | break; 49 | default: 50 | double? _width = YZDynamicWidgetUtils.doubleAdapter(props.width); 51 | double? _height = YZDynamicWidgetUtils.doubleAdapter(props.height); 52 | _widget = SizedBox( 53 | width: _width, 54 | height: _height, 55 | child: _child 56 | ); 57 | } 58 | 59 | return _widget; 60 | } 61 | 62 | } 63 | 64 | /// The props of SizedBox config 65 | class YZSizedBoxConfig { 66 | String? type; //expand/shrink/fromSize 67 | String? width; 68 | String? height; 69 | Map? size; 70 | Map? child; 71 | 72 | YZSizedBoxConfig( 73 | {this.type, 74 | this.width, 75 | this.height, 76 | this.child}); 77 | 78 | YZSizedBoxConfig.fromJson(Map? json) { 79 | json ??= {}; 80 | type = json['type']; 81 | width = json['width']; 82 | height = json['height']; 83 | child = json['child']; 84 | } 85 | } -------------------------------------------------------------------------------- /lib/widgets/basic/action.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-09-16 22:24:50 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-09-24 09:44:37 6 | */ 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:yz_flutter_dynamic/main.dart'; 10 | 11 | import 'event.dart'; 12 | import 'widget.dart'; 13 | export '../../tools/action.dart'; 14 | 15 | mixin YZDynamicWidgetActionServer { 16 | 17 | //获取事件对应的actions,action有3个来源:控件本身、别的控件、页面区域、公共区域 18 | //Get actions corresponding to the event. There are three source: Self DynamicWidget/Other DynamicWidget in page/Public DynamicWidget 19 | List? getActionsOfEvent( 20 | BuildContext? context, 21 | YZDynamicWidgetEventType? eventType, 22 | String? name, 23 | List? xEvents, 24 | Map? xActions 25 | ) { 26 | 27 | List? _xEvents = xEvents; 28 | 29 | List? actions = []; 30 | _xEvents?.forEach((ejson) { 31 | if (ejson is Map) { 32 | YZDynamicWidgetEventConfig e = YZDynamicWidgetEventConfig.fromJson(ejson); 33 | String? _name = e.name; 34 | YZDynamicWidgetEventType? _eventType = e.eventType; 35 | if (_eventType == eventType && _name == name && e.actions != null) { 36 | actions = YZDynamicActionTool.getFullfillActions(e.actions, xActions, context); 37 | } 38 | } 39 | }); 40 | 41 | return actions; 42 | } 43 | 44 | //获取简单属性actions对应的actions,action有3个来源:控件本身、别的控件、公共区域 45 | //Get actions corresponding to the actions with simple properties. There are three source: Self DynamicWidget/Other DynamicWidget in page/Public DynamicWidget 46 | List? getActionsOfSimpleActions( 47 | List simpleActions, 48 | Map xActions, 49 | [BuildContext? context] 50 | ) { 51 | return YZDynamicActionTool.getFullfillActions(simpleActions, xActions); 52 | } 53 | 54 | void triggerActions( 55 | YZDynamicWidgetBasicState state, 56 | List actions, 57 | {Map? localVariables} 58 | ){ 59 | return YZDynamicActionTool.triggerActions(state, actions, localVariables: localVariables); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /lib/widgets/basic/data.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-09-19 23:09:26 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-09-20 18:15:57 6 | */ 7 | 8 | import '../../tools/network.dart'; 9 | 10 | mixin YZDynamicWidgetDataServer { 11 | 12 | ///获取控件显示的数据 13 | ///Get widget display data 14 | List getXData(List? xdata){ 15 | 16 | List _data = []; 17 | 18 | if (xdata != null && xdata.isNotEmpty) { 19 | xdata.forEach((item){ 20 | Map _item = item as Map; 21 | _data.add(YZDynamicWidgetDataConfig.fromJson(_item)); 22 | }); 23 | } 24 | 25 | return _data; 26 | } 27 | 28 | ///获取控件显示request 29 | ///Get widget display request 30 | ///Default get first one 31 | YZDynamicRequest? getRequest(List? xdata, [String? name]) { 32 | YZDynamicRequest? request; 33 | 34 | if (xdata != null && xdata.isNotEmpty) { 35 | if (name == null || name.isEmpty) { 36 | request = YZDynamicRequest.fromJson(xdata[0]['request']); 37 | } else { 38 | for (Map item in xdata) { 39 | if (name == item[name]) { 40 | request = YZDynamicRequest.fromJson(item['request']); 41 | break; 42 | } 43 | } 44 | } 45 | } 46 | 47 | return request; 48 | } 49 | 50 | ///获取控件显示定义数据,支持透传 51 | ///Get widget display defined showdata supporting unvarnished transmission 52 | ///Default get first one 53 | dynamic getShowData(List? xdata, [String? name]) { 54 | dynamic showdata; 55 | 56 | if (xdata != null && xdata.isNotEmpty) { 57 | if (name == null || name.isEmpty) { 58 | showdata = xdata[0]['showdata']; 59 | } else { 60 | for (Map item in xdata) { 61 | if (name == item[name]) { 62 | showdata = item['showdata']; 63 | break; 64 | } 65 | } 66 | } 67 | } 68 | 69 | return showdata; 70 | } 71 | 72 | } 73 | 74 | class YZDynamicWidgetDataConfig { 75 | String? name; 76 | YZDynamicRequest? request; 77 | dynamic showdata; 78 | 79 | YZDynamicWidgetDataConfig({this.name, this.request, this.showdata}); 80 | 81 | YZDynamicWidgetDataConfig.fromJson(Map json) { 82 | name = json['name']; 83 | request = YZDynamicRequest.fromJson(json['request']); 84 | showdata = json['showdata']; 85 | 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /lib/widgets/basic/event.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-09-17 14:37:45 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-09-19 22:49:16 6 | */ 7 | 8 | import 'package:flutter/material.dart'; 9 | import '../../tools/action.dart'; 10 | 11 | abstract class YZDynamicWidgetEvent{ 12 | 13 | // @protected 14 | void triggerEvent([YZDynamicWidgetEventType eventType, String? name]); 15 | 16 | } 17 | 18 | mixin YZDynamicWidgetEventServer implements YZDynamicWidgetEvent { 19 | 20 | ///给控件套上事件 21 | ///Wrap the event to the widget 22 | ///这个方法只针对基础组件进行绑定,不针对有子对象(YZDynamicWidgetEventConfig.name)的组件进行区分子对象绑定 23 | Widget buildWithEvents(Widget widget, List? events){ 24 | Widget _widget; 25 | 26 | if (events != null && events.isNotEmpty) { 27 | Function? _onClick; 28 | Function? _onLongPress; 29 | Function? _onDoubleTap; 30 | for (Map ev in events) { 31 | YZDynamicWidgetEventConfig m = YZDynamicWidgetEventConfig.fromJson(ev); 32 | switch (m.eventType) { 33 | case YZDynamicWidgetEventType.onClick: 34 | _onClick = (){ 35 | triggerEvent(YZDynamicWidgetEventType.onClick); 36 | }; 37 | break; 38 | case YZDynamicWidgetEventType.onLongPress: 39 | _onLongPress = (){ 40 | triggerEvent(YZDynamicWidgetEventType.onLongPress); 41 | }; 42 | break; 43 | case YZDynamicWidgetEventType.onDoubleTap: 44 | _onDoubleTap = (){ 45 | triggerEvent(YZDynamicWidgetEventType.onDoubleTap); 46 | }; 47 | break; 48 | default: 49 | } 50 | } 51 | _widget = GestureDetector( 52 | behavior: HitTestBehavior.opaque, 53 | child: widget, 54 | onTap: (){ 55 | if (_onClick != null)_onClick(); 56 | }, 57 | onLongPress: (){ 58 | if (_onLongPress != null)_onLongPress(); 59 | }, 60 | onDoubleTap: (){ 61 | if (_onDoubleTap != null)_onDoubleTap(); 62 | }, 63 | ); 64 | } else { 65 | _widget = widget; 66 | } 67 | 68 | return _widget; 69 | } 70 | 71 | } 72 | 73 | //The type of event / 事件类型 74 | enum YZDynamicWidgetEventType { 75 | onClick, //onTap/onPress 76 | onLongPress, 77 | onDoubleTap, 78 | onValueChanged, 79 | } 80 | 81 | class YZDynamicWidgetEventConfig { 82 | String? name; 83 | YZDynamicWidgetEventType? eventType; 84 | List? actions; 85 | String? code; 86 | 87 | YZDynamicWidgetEventConfig( 88 | {this.name, this.eventType, this.actions, this.code}); 89 | 90 | YZDynamicWidgetEventConfig.fromJson(Map json) { 91 | name = json['name']; 92 | dynamic _eventType = json['eventType']; 93 | if (_eventType == 'onClick' || _eventType == 'onTap' || _eventType == 'onPress' || _eventType == 'click') { 94 | eventType = YZDynamicWidgetEventType.onClick; 95 | } else if (_eventType == 'onLongPress' || _eventType == 'longclick') { 96 | eventType = YZDynamicWidgetEventType.onLongPress; 97 | } else if (_eventType == 'onDoubleTap' || _eventType == 'dblclick') { 98 | eventType = YZDynamicWidgetEventType.onDoubleTap; 99 | } if (_eventType == 'onValueChanged') { 100 | eventType = YZDynamicWidgetEventType.onValueChanged; 101 | } 102 | if (json['actions'] != null) { 103 | actions = (json['actions'] as List).map((e) => YZDynamicActionConfig.fromJson(e)).toList(); 104 | } 105 | code = json['code']; 106 | } 107 | } 108 | 109 | -------------------------------------------------------------------------------- /lib/widgets/basic/handler.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-09-02 11:20:05 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-09-17 17:45:04 6 | **/ 7 | 8 | import 'package:flutter/material.dart'; 9 | 10 | /// extends this class to make a Flutter widget base. 11 | abstract class YZDynamicBasicWidgetHandler { 12 | 13 | /// the widget type name 14 | String get widgetName; 15 | 16 | /// parse the json map into a flutter widget. 17 | Widget build(Map json, {Key? key, BuildContext? buildContext}); 18 | 19 | } -------------------------------------------------------------------------------- /lib/widgets/center.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Center 3 | * @Author: chenlijiao 4 | * @Date: 2021-03-16 15:47:51 5 | * @LastEditors: chenlijiao 6 | * @LastEditTime: 2021-03-16 15:50:03 7 | */ 8 | 9 | import 'package:flutter/material.dart'; 10 | import 'package:yz_flutter_dynamic/tools/common.dart'; 11 | import 'basic/handler.dart'; 12 | import 'basic/utils.dart'; 13 | import 'basic/widget.dart'; 14 | 15 | class YZCenterHandler extends YZDynamicBasicWidgetHandler { 16 | @override 17 | String get widgetName => 'Center'; 18 | 19 | @override 20 | Widget build(Map json, 21 | {Key? key, BuildContext? buildContext}) { 22 | return _Builder(json, key: key); 23 | } 24 | } 25 | 26 | class _Builder extends YZDynamicBaseWidget { 27 | final Map json; 28 | 29 | _Builder(this.json, {Key? key}) : super(json, key: key); 30 | 31 | @override 32 | _BuilderState createState() => _BuilderState(); 33 | } 34 | 35 | class _BuilderState extends YZDynamicWidgetBasicState<_Builder> { 36 | //Deal with props / 处理控件属性 37 | late YZCenterConfig props; 38 | double? _widthFactor; 39 | double? _heightFactor; 40 | Widget? _child; 41 | 42 | @override 43 | void initState() { 44 | super.initState(); 45 | 46 | //Deal with props / 处理控件属性 47 | props = YZCenterConfig.fromJson(super.config?.props ?? {}); 48 | _widthFactor = YZDynamicWidgetUtils.doubleAdapter(props.widthFactor); 49 | _heightFactor = YZDynamicWidgetUtils.doubleAdapter(props.heightFactor); 50 | _child = props.child == null 51 | ? null 52 | : YZDynamicCommon.buildWidget(props.child, context: context); 53 | } 54 | 55 | @override 56 | Widget build(BuildContext context) { 57 | Widget _widget; 58 | 59 | Center _subwidget = Center( 60 | widthFactor: _widthFactor, 61 | heightFactor: _heightFactor, 62 | child: _child, 63 | ); 64 | 65 | //Deal with events / 处理事件 66 | _widget = super.buildWithEvents(_subwidget, super.config?.xEvents); 67 | 68 | return _widget; 69 | } 70 | 71 | @override 72 | void registerActions() { 73 | //Deal with action / 处理事件实现 74 | } 75 | 76 | } 77 | 78 | /// The props of Center config 79 | class YZCenterConfig { 80 | String? widthFactor; 81 | String? heightFactor; 82 | Map? child; 83 | 84 | YZCenterConfig({this.heightFactor, this.widthFactor, this.child}); 85 | 86 | YZCenterConfig.fromJson(Map? json) { 87 | json ??= {}; 88 | widthFactor = json['widthFactor']; 89 | heightFactor = json['heightFactor']; 90 | child = json['child']; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /lib/widgets/checkbox.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-11-18 12:04:45 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-11-18 12:08:18 6 | */ 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:yz_flutter_dynamic/tools/common.dart'; 10 | import 'basic/event.dart'; 11 | import 'basic/handler.dart'; 12 | import 'basic/utils.dart'; 13 | import 'basic/widget.dart'; 14 | 15 | class YZCheckboxHandler extends YZDynamicBasicWidgetHandler { 16 | @override 17 | Widget build(Map json, 18 | {Key? key, BuildContext? buildContext}) { 19 | return _Builder(json, key: key); 20 | } 21 | 22 | @override 23 | String get widgetName => 'Checkbox'; 24 | } 25 | 26 | class _Builder extends YZDynamicBaseWidget { 27 | final Map json; 28 | 29 | _Builder(this.json, {Key? key}) : super(json, key: key); 30 | 31 | @override 32 | _BuilderState createState() => _BuilderState(); 33 | } 34 | 35 | class _BuilderState extends YZDynamicWidgetBasicState<_Builder> { 36 | //Deal with props / 处理控件属性 37 | late YZCheckboxConfig props; 38 | Color? _activeColor; 39 | bool? _value; 40 | Color? _checkColor; 41 | bool? _tristate; 42 | Color? _focusColor; 43 | Color? _hoverColor; 44 | MaterialTapTargetSize? _materialTapTargetSize; 45 | 46 | @override 47 | void initState() { 48 | super.initState(); 49 | 50 | //Deal with props / 处理控件属性 51 | props = YZCheckboxConfig.fromJson(super.config?.props ?? {}); 52 | _value = YZDynamicWidgetUtils.boolAdapter(props.value); 53 | _activeColor = YZDynamicWidgetUtils.colorAdapter(props.activeColor); 54 | _checkColor = YZDynamicWidgetUtils.colorAdapter(props.checkColor); 55 | _focusColor = YZDynamicWidgetUtils.colorAdapter(props.focusColor); 56 | _hoverColor = YZDynamicWidgetUtils.colorAdapter(props.hoverColor); 57 | _materialTapTargetSize = YZDynamicWidgetUtils.materialTapTargetSizeAdapter( 58 | props.materialTapTargetSize); 59 | _tristate = YZDynamicWidgetUtils.boolAdapter(props.tristate); 60 | } 61 | 62 | @override 63 | Widget build(BuildContext context) { 64 | Checkbox _widget; 65 | 66 | _widget = Checkbox( 67 | value: _value, 68 | activeColor: _activeColor, 69 | checkColor: _checkColor, 70 | tristate: _tristate ?? false, 71 | focusNode: null, 72 | autofocus: false, 73 | visualDensity: null, 74 | mouseCursor: null, 75 | focusColor: _focusColor, 76 | hoverColor: _hoverColor, 77 | materialTapTargetSize: _materialTapTargetSize, 78 | onChanged: (value) { 79 | this.value = value.toString(); 80 | _value = !(_value!); 81 | setState(() {}); 82 | super.triggerEvent(YZDynamicWidgetEventType.onValueChanged); 83 | }, 84 | ); 85 | 86 | return _widget; 87 | } 88 | 89 | @override 90 | void registerActions() { 91 | //Deal with action / 处理事件实现 92 | actionFunctions['setState'] = stateSetter; 93 | } 94 | 95 | void stateSetter(BuildContext? triggerContext, { 96 | Map? params, 97 | YZDynamicRequest? request, 98 | List? rules, 99 | Map? localVariables, 100 | State? state, 101 | }) { 102 | print('Execute xAction: ${this.runtimeType} setState'); 103 | if (mounted) { 104 | setState(() {}); 105 | } 106 | } 107 | } 108 | 109 | /// The props of Checkbox config 110 | class YZCheckboxConfig { 111 | String? activeColor; 112 | String? value; 113 | String? checkColor; 114 | String? tristate; 115 | String? focusColor; 116 | String? hoverColor; 117 | String? materialTapTargetSize; 118 | 119 | YZCheckboxConfig( 120 | {this.activeColor, this.checkColor, this.value, this.tristate}); 121 | 122 | YZCheckboxConfig.fromJson(Map? json) { 123 | json ??= {}; 124 | activeColor = json['activeColor']; 125 | value = json['value']; 126 | checkColor = json['checkColor']; 127 | tristate = json['tristate']; 128 | focusColor = json['focusColor']; 129 | hoverColor = json['hoverColor']; 130 | materialTapTargetSize = json['materialTapTargetSize']; 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /lib/widgets/clip_rrect.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Descripttion: 3 | * @version: ClipRRect 4 | * @Author: dingjian 5 | * @Date: 2021-05-14 15:21:52 6 | * @LastEditors: dingjian 7 | * @LastEditTime: 2021-05-14 18:52:07 8 | */ 9 | 10 | import 'package:flutter/material.dart'; 11 | import 'package:yz_flutter_dynamic/tools/common.dart'; 12 | import 'package:yz_flutter_dynamic/widgets/basic/handler.dart'; 13 | import 'package:yz_flutter_dynamic/widgets/basic/utils.dart'; 14 | import 'package:yz_flutter_dynamic/widgets/basic/widget.dart'; 15 | 16 | class YZClipRRectHandler extends YZDynamicBasicWidgetHandler { 17 | @override 18 | String get widgetName => 'ClipRRect'; 19 | 20 | @override 21 | Widget build(Map json, 22 | {Key? key, BuildContext? buildContext}) { 23 | return _Builder(json, key: key); 24 | } 25 | } 26 | 27 | class _Builder extends YZDynamicBaseWidget { 28 | final Map json; 29 | 30 | _Builder(this.json, {Key? key}) : super(json, key: key); 31 | 32 | @override 33 | _BuilderState createState() => _BuilderState(); 34 | } 35 | 36 | class _BuilderState extends YZDynamicWidgetBasicState<_Builder> { 37 | late YZClipRRectConfig props; 38 | BorderRadius? _borderRadius; 39 | Clip? _clipBehavior; 40 | Widget? _child; 41 | 42 | @override 43 | void initState() { 44 | super.initState(); 45 | 46 | //Deal with props / 处理控件属性 47 | props = YZClipRRectConfig.fromJson(super.config?.props ?? {}); 48 | _clipBehavior = 49 | YZDynamicWidgetUtils.clipBehaviorAdapter(props.clipBehavior); 50 | _borderRadius = 51 | YZDynamicWidgetUtils.borderRadiusAdapter(props.borderRadius); 52 | _child = props.child == null 53 | ? null 54 | : YZDynamicCommon.buildWidget(props.child, context: context); 55 | } 56 | 57 | @override 58 | Widget build(BuildContext context) { 59 | Widget _widget; 60 | 61 | ClipRRect _subwidget = ClipRRect( 62 | clipBehavior: _clipBehavior ?? Clip.antiAlias, 63 | borderRadius: _borderRadius, 64 | child: _child, 65 | ); 66 | 67 | //Deal with events / 处理事件 68 | _widget = super.buildWithEvents(_subwidget, super.config?.xEvents); 69 | 70 | return _widget; 71 | } 72 | 73 | @override 74 | void registerActions() { 75 | //Deal with action / 处理事件实现 76 | } 77 | 78 | } 79 | 80 | /// The props of Wrap config 81 | class YZClipRRectConfig { 82 | Map? borderRadius; 83 | String? clipBehavior; 84 | Map? child; 85 | 86 | YZClipRRectConfig({this.borderRadius, this.clipBehavior, this.child}); 87 | 88 | YZClipRRectConfig.fromJson(Map? json) { 89 | json ??= {}; 90 | borderRadius = json['borderRadius']; 91 | clipBehavior = json['clipBehavior']; 92 | child = json['child']; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /lib/widgets/column.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-11-02 22:30:11 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-11-19 10:11:22 6 | */ 7 | 8 | import 'package:flutter/material.dart'; 9 | import '../tools/common.dart'; 10 | import 'basic/utils.dart'; 11 | import 'basic/handler.dart'; 12 | import 'basic/widget.dart'; 13 | 14 | /// Column handler 15 | class YZColumnHandler extends YZDynamicBasicWidgetHandler { 16 | 17 | @override 18 | String get widgetName => 'Column'; 19 | 20 | @override 21 | Widget build(Map json, {Key? key, BuildContext? buildContext}) { 22 | return _Builder(json, key:key); 23 | } 24 | 25 | } 26 | 27 | class _Builder extends YZDynamicBaseWidget { 28 | 29 | final Map json; 30 | 31 | _Builder(this.json, {Key? key}): super(json, key: key); 32 | 33 | @override 34 | _BuilderState createState() => _BuilderState(); 35 | } 36 | 37 | class _BuilderState extends YZDynamicWidgetBasicState<_Builder> { 38 | 39 | @override 40 | void initState() { 41 | super.initState(); 42 | } 43 | 44 | @override 45 | Widget build(BuildContext context) { 46 | Widget _widget; 47 | 48 | //Deal with props / 处理控件属性 49 | YZColumnConfig props = YZColumnConfig.fromJson(super.config?.props ?? {}); 50 | MainAxisAlignment? _mainAxisAlignment = YZDynamicWidgetUtils.mainAxisAlignmentAdapter(props.mainAxisAlignment); 51 | MainAxisSize? _mainAxisSize = YZDynamicWidgetUtils.mainAxisSizeAdapter(props.mainAxisSize); 52 | CrossAxisAlignment? _crossAxisAlignment = YZDynamicWidgetUtils.crossAxisAlignmentAdapter(props.crossAxisAlignment); 53 | TextDirection? _textDirection = YZDynamicWidgetUtils.textDirectionAdapter(props.textDirection); 54 | VerticalDirection? _verticalDirection = YZDynamicWidgetUtils.verticalDirectionAdapter(props.verticalDirection); 55 | TextBaseline? _textBaseline = YZDynamicWidgetUtils.textBaselineAdapter(props.textBaseline); 56 | List? _children; 57 | if (props.children != null) { 58 | _children = []; 59 | props.children?.forEach((e) { 60 | Widget? _child = YZDynamicCommon.buildWidget(e, context: context); 61 | if (_child == null)return; 62 | _children!.add(_child); 63 | }); 64 | } 65 | 66 | Column _subwidget = Column( 67 | mainAxisAlignment: _mainAxisAlignment ?? MainAxisAlignment.start, 68 | mainAxisSize: _mainAxisSize ?? MainAxisSize.max, 69 | crossAxisAlignment: _crossAxisAlignment ?? CrossAxisAlignment.center, 70 | textDirection: _textDirection, 71 | verticalDirection: _verticalDirection ?? VerticalDirection.down, 72 | textBaseline: _textBaseline, 73 | children: _children!, 74 | ); 75 | 76 | //Deal with events / 处理事件 77 | _widget = super.buildWithEvents(_subwidget, super.config?.xEvents); 78 | 79 | return _widget; 80 | } 81 | 82 | @override 83 | void registerActions() { 84 | //Deal with action / 处理事件实现 85 | } 86 | 87 | } 88 | 89 | /// The props of Column config 90 | class YZColumnConfig { 91 | String? mainAxisAlignment; 92 | String? mainAxisSize; 93 | String? crossAxisAlignment; 94 | String? textDirection; 95 | String? verticalDirection; 96 | String? textBaseline; 97 | List? children; 98 | 99 | YZColumnConfig( 100 | {this.mainAxisAlignment, 101 | this.mainAxisSize, 102 | this.crossAxisAlignment, 103 | this.textDirection, 104 | this.verticalDirection, 105 | this.textBaseline, 106 | this.children}); 107 | 108 | YZColumnConfig.fromJson(Map? json) { 109 | json ??= {}; 110 | mainAxisAlignment = json['mainAxisAlignment']; 111 | mainAxisSize = json['mainAxisSize']; 112 | crossAxisAlignment = json['crossAxisAlignment']; 113 | textDirection = json['textDirection']; 114 | verticalDirection = json['verticalDirection']; 115 | textBaseline = json['textBaseline']; 116 | if (json['children'] != null) { 117 | children = []; 118 | json['children'].forEach((v) { 119 | children!.add(v); 120 | }); 121 | } 122 | } 123 | 124 | } -------------------------------------------------------------------------------- /lib/widgets/dialog.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-11-26 18:11:05 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-11-26 18:26:59 6 | */ 7 | 8 | 9 | import 'package:flutter/material.dart'; 10 | import '../tools/common.dart'; 11 | import 'basic/utils.dart'; 12 | import 'basic/handler.dart'; 13 | import 'basic/widget.dart'; 14 | 15 | /// Dialog handler 16 | class YZDialogHandler extends YZDynamicBasicWidgetHandler { 17 | 18 | @override 19 | String get widgetName => 'Dialog'; 20 | 21 | @override 22 | Widget build(Map json, {Key? key, BuildContext? buildContext}) { 23 | return _Builder(json, key:key); 24 | } 25 | 26 | } 27 | 28 | class _Builder extends YZDynamicBaseWidget { 29 | 30 | final Map json; 31 | 32 | _Builder(this.json, {Key? key}): super(json, key: key); 33 | 34 | @override 35 | _BuilderState createState() => _BuilderState(); 36 | } 37 | 38 | class _BuilderState extends YZDynamicWidgetBasicState<_Builder> { 39 | 40 | //Deal with props / 处理控件属性 41 | late YZDialogConfig props; 42 | EdgeInsets? _insetPadding; 43 | double? _elevation; 44 | Curve? _insetAnimationCurve; 45 | Clip? _clipBehavior; 46 | Widget? _child; 47 | Color? _backgroundColor; 48 | 49 | @override 50 | void initState() { 51 | super.initState(); 52 | 53 | //Deal with props / 处理控件属性 54 | props = YZDialogConfig.fromJson(super.config?.props ?? {}); 55 | _backgroundColor = YZDynamicWidgetUtils.colorAdapter(props.backgroundColor); 56 | _insetPadding = YZDynamicWidgetUtils.edgeInsetAdapter(props.insetPadding); 57 | _elevation = YZDynamicWidgetUtils.doubleAdapter(props.elevation); 58 | _insetAnimationCurve = YZDynamicWidgetUtils.curveAdapter(props.insetAnimationCurve); 59 | _clipBehavior = YZDynamicWidgetUtils.clipBehaviorAdapter(props.clipBehavior); 60 | _child = props.child == null ? null : YZDynamicCommon.buildWidget(props.child, context: context); 61 | } 62 | 63 | @override 64 | Widget build(BuildContext context) { 65 | Widget _widget; 66 | 67 | Dialog _subwidget = Dialog( 68 | backgroundColor: _backgroundColor, 69 | elevation: _elevation, 70 | insetAnimationDuration: const Duration(milliseconds: 100), 71 | insetAnimationCurve: _insetAnimationCurve ?? Curves.decelerate, 72 | insetPadding: _insetPadding, 73 | clipBehavior: _clipBehavior ?? Clip.none, 74 | shape: null, 75 | child: _child, 76 | ); 77 | 78 | //Deal with events / 处理事件 79 | _widget = super.buildWithEvents(_subwidget, super.config?.xEvents); 80 | 81 | return _widget; 82 | } 83 | 84 | @override 85 | void registerActions() { 86 | //Deal with action / 处理事件实现 87 | actionFunctions['setState'] = stateSetter; 88 | } 89 | 90 | void stateSetter(BuildContext? triggerContext, { 91 | Map? params, 92 | YZDynamicRequest? request, 93 | List? rules, 94 | Map? localVariables, 95 | State? state, 96 | }) { 97 | print('Execute xAction: ${this.runtimeType} setState'); 98 | if (mounted) { 99 | setState(() {}); 100 | } 101 | } 102 | 103 | } 104 | 105 | /// The props of Dialog config 106 | class YZDialogConfig { 107 | List? insetPadding; 108 | String? backgroundColor; 109 | String? elevation; 110 | String? insetAnimationCurve; 111 | String? clipBehavior; 112 | Map? child; 113 | 114 | YZDialogConfig( 115 | {this.insetPadding, 116 | this.backgroundColor, 117 | this.elevation, 118 | this.insetAnimationCurve, 119 | this.clipBehavior, 120 | this.child}); 121 | 122 | YZDialogConfig.fromJson(Map? json) { 123 | json ??= {}; 124 | insetPadding = YZDynamicCommon.dynamicToList(json['insetPadding']); 125 | backgroundColor = json['backgroundColor']; 126 | elevation = json['elevation']; 127 | insetAnimationCurve = json['insetAnimationCurve']; 128 | clipBehavior = json['clipBehavior']; 129 | child = json['child']; 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /lib/widgets/divider.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Divider分割线 3 | * @Author: chenlijiao 4 | * @Date: 2021-02-25 20:19:26 5 | * @LastEditors: chenlijiao 6 | * @LastEditTime: 2021-02-26 18:25:28 7 | */ 8 | 9 | import 'dart:ui'; 10 | import 'package:yz_flutter_dynamic/main.dart'; 11 | import 'package:yz_flutter_dynamic/widgets/basic/handler.dart'; 12 | import 'basic/utils.dart'; 13 | import 'basic/widget.dart'; 14 | 15 | class YZDividerHandler extends YZDynamicBasicWidgetHandler { 16 | @override 17 | String get widgetName => 'Divider'; 18 | 19 | @override 20 | Widget build(Map json, 21 | {Key? key, BuildContext? buildContext}) { 22 | return _Builder(json, key: key); 23 | } 24 | } 25 | 26 | class _Builder extends YZDynamicBaseWidget { 27 | final Map json; 28 | 29 | _Builder(this.json, {Key? key}) : super(json, key: key); 30 | 31 | @override 32 | _BuilderState createState() => _BuilderState(); 33 | } 34 | 35 | class _BuilderState extends YZDynamicWidgetBasicState<_Builder> { 36 | late YZDividerConfig props; 37 | 38 | double? _thickness; 39 | double? _height; 40 | double? _indent; 41 | double? _endIndent; 42 | Color? _color; 43 | 44 | @override 45 | void initState() { 46 | super.initState(); 47 | 48 | //Deal with props / 处理控件属性 49 | props = YZDividerConfig.fromJson(super.config?.props ?? {}); 50 | _color = YZDynamicWidgetUtils.colorAdapter(props.color); 51 | _height = YZDynamicWidgetUtils.doubleAdapter(props.height); 52 | _thickness = YZDynamicWidgetUtils.doubleAdapter(props.thickness); 53 | _indent = YZDynamicWidgetUtils.doubleAdapter(props.indent); 54 | _endIndent = YZDynamicWidgetUtils.doubleAdapter(props.endIndent); 55 | } 56 | 57 | @override 58 | Widget build(BuildContext context) { 59 | Widget _widget; 60 | 61 | Divider _subwidget = Divider( 62 | color: _color, 63 | height: _height, 64 | thickness: _thickness, 65 | indent: _indent, 66 | endIndent: _endIndent, 67 | ); 68 | 69 | //Deal with events / 处理事件 70 | _widget = super.buildWithEvents(_subwidget, super.config?.xEvents); 71 | 72 | return _widget; 73 | } 74 | 75 | @override 76 | void registerActions() { 77 | //Deal with action / 处理事件实现 78 | } 79 | 80 | } 81 | 82 | class YZDividerConfig { 83 | String? color; 84 | String? height; 85 | String? thickness; 86 | String? indent; 87 | String? endIndent; 88 | 89 | YZDividerConfig( 90 | {this.color, this.height, this.thickness, this.endIndent, this.indent}); 91 | 92 | YZDividerConfig.fromJson(Map? json) { 93 | json ??= {}; 94 | color = json['color']; 95 | height = json['height']; 96 | thickness = json['thickness']; 97 | indent = json['indent']; 98 | endIndent = json['endIndent']; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /lib/widgets/expanded.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-11-03 11:32:15 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-11-03 11:38:13 6 | */ 7 | 8 | import 'package:flutter/material.dart'; 9 | import '../tools/common.dart'; 10 | import 'basic/utils.dart'; 11 | import 'basic/handler.dart'; 12 | import 'basic/widget.dart'; 13 | 14 | /// Expanded handler 15 | class YZExpandedHandler extends YZDynamicBasicWidgetHandler { 16 | 17 | @override 18 | String get widgetName => 'Expanded'; 19 | 20 | @override 21 | Widget build(Map json, {Key? key, BuildContext? buildContext}) { 22 | return _Builder(json, key:key); 23 | } 24 | 25 | } 26 | 27 | class _Builder extends YZDynamicBaseWidget { 28 | 29 | final Map json; 30 | 31 | _Builder(this.json, {Key? key}): super(json, key: key); 32 | 33 | @override 34 | _BuilderState createState() => _BuilderState(); 35 | } 36 | 37 | class _BuilderState extends YZDynamicWidgetBasicState<_Builder> { 38 | 39 | @override 40 | void initState() { 41 | super.initState(); 42 | } 43 | 44 | @override 45 | Widget build(BuildContext context) { 46 | Widget _widget; 47 | 48 | //Deal with props / 处理控件属性 49 | YZExpandedConfig props = YZExpandedConfig.fromJson(super.config?.props ?? {}); 50 | int? _flex = YZDynamicWidgetUtils.intAdapter(props.flex); 51 | Widget? _child = props.child == null ? null : YZDynamicCommon.buildWidget(props.child, context: context); 52 | 53 | Expanded _subwidget = Expanded( 54 | flex: _flex ?? 1, 55 | child: _child! 56 | ); 57 | 58 | //Deal with events / 处理事件 59 | _widget = super.buildWithEvents(_subwidget, super.config?.xEvents); 60 | 61 | return _widget; 62 | } 63 | 64 | @override 65 | void registerActions() { 66 | 67 | } 68 | 69 | } 70 | 71 | /// The props of Expanded config 72 | class YZExpandedConfig { 73 | String? flex; 74 | Map? child; 75 | 76 | YZExpandedConfig( 77 | {this.flex, 78 | this.child}); 79 | 80 | YZExpandedConfig.fromJson(Map? json) { 81 | json ??= {}; 82 | flex = json['flex']; 83 | child = json['child']; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /lib/widgets/flexible.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Flexible 3 | * @Author: chenlijiao 4 | * @Date: 2021-03-15 11:04:29 5 | * @LastEditors: chenlijiao 6 | * @LastEditTime: 2021-03-18 17:26:16 7 | */ 8 | 9 | import 'package:flutter/material.dart'; 10 | import 'package:yz_flutter_dynamic/tools/common.dart'; 11 | 12 | import 'basic/handler.dart'; 13 | import 'basic/utils.dart'; 14 | import 'basic/widget.dart'; 15 | 16 | class YZFlexibleHandler extends YZDynamicBasicWidgetHandler { 17 | @override 18 | String get widgetName => 'Flexible'; 19 | 20 | @override 21 | Widget build(Map json, 22 | {Key? key, BuildContext? buildContext}) { 23 | return _Builder(json, key: key); 24 | } 25 | } 26 | 27 | class _Builder extends YZDynamicBaseWidget { 28 | final Map json; 29 | 30 | _Builder(this.json, {Key? key}) : super(json, key: key); 31 | 32 | @override 33 | _BuilderState createState() => _BuilderState(); 34 | } 35 | 36 | class _BuilderState extends YZDynamicWidgetBasicState<_Builder> { 37 | @override 38 | void initState() { 39 | super.initState(); 40 | } 41 | 42 | @override 43 | Widget build(BuildContext context) { 44 | Widget _widget; 45 | 46 | //Deal with props / 处理控件属性 47 | YZFlexibleConfig props = 48 | YZFlexibleConfig.fromJson(super.config?.props ?? {}); 49 | int? _flex = YZDynamicWidgetUtils.intAdapter(props.flex); 50 | Widget? _child = props.child == null 51 | ? null 52 | : YZDynamicCommon.buildWidget(props.child, context: context); 53 | 54 | Flexible _subwidget = 55 | Flexible(flex: _flex ?? 1, fit: FlexFit.loose, child: _child!); 56 | 57 | //Deal with events / 处理事件 58 | _widget = super.buildWithEvents(_subwidget, super.config?.xEvents); 59 | 60 | return _widget; 61 | } 62 | 63 | @override 64 | void registerActions() {} 65 | } 66 | 67 | /// The props of Flexible config 68 | class YZFlexibleConfig { 69 | String? flex; 70 | Map? child; 71 | 72 | YZFlexibleConfig({this.flex, this.child}); 73 | 74 | YZFlexibleConfig.fromJson(Map? json) { 75 | json ??= {}; 76 | flex = json['flex']; 77 | child = json['child']; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /lib/widgets/form.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-09-13 21:03:33 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-11-03 11:37:43 6 | **/ 7 | 8 | import 'package:flutter/material.dart'; 9 | 10 | /// encapsulation of Form 11 | class YZForm extends Form { 12 | 13 | YZForm({ 14 | Key? key, 15 | Widget? child, 16 | AutovalidateMode? autovalidateMode, 17 | WillPopCallback? onWillPop, 18 | VoidCallback? onChanged, 19 | }) : assert(child != null), 20 | super( 21 | key: key, 22 | child: child!, 23 | autovalidateMode: autovalidateMode, 24 | onWillPop: onWillPop, 25 | onChanged: onChanged 26 | ); 27 | } -------------------------------------------------------------------------------- /lib/widgets/gesture_detector.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: GestureDetector 3 | * @Author: chenlijiao 4 | * @Date: 2021-03-19 11:30:46 5 | * @LastEditors: chenlijiao 6 | * @LastEditTime: 2021-03-19 14:40:45 7 | */ 8 | 9 | import 'package:flutter/gestures.dart'; 10 | import 'package:flutter/material.dart'; 11 | import 'package:yz_flutter_dynamic/tools/common.dart'; 12 | import 'package:yz_flutter_dynamic/widgets/basic/utils.dart'; 13 | 14 | import 'basic/event.dart'; 15 | import 'basic/handler.dart'; 16 | import 'basic/widget.dart'; 17 | 18 | class YZGestureDetectorHandler extends YZDynamicBasicWidgetHandler { 19 | @override 20 | String get widgetName => 'GestureDetector'; 21 | 22 | @override 23 | Widget build(Map json, 24 | {Key? key, BuildContext? buildContext}) { 25 | return _Builder(json, key: key); 26 | } 27 | } 28 | 29 | class _Builder extends YZDynamicBaseWidget { 30 | final Map json; 31 | 32 | _Builder(this.json, {Key? key}) : super(json, key: key); 33 | 34 | @override 35 | _BuilderState createState() => _BuilderState(); 36 | } 37 | 38 | class _BuilderState extends YZDynamicWidgetBasicState<_Builder> { 39 | @override 40 | void initState() { 41 | super.initState(); 42 | } 43 | 44 | @override 45 | Widget build(BuildContext context) { 46 | Widget _widget; 47 | 48 | //Deal with props / 处理控件属性 49 | YZGestureDetectorConfig props = 50 | YZGestureDetectorConfig.fromJson(super.config?.props ?? {}); 51 | HitTestBehavior? _behavior = 52 | YZDynamicWidgetUtils.hitTestBehaviorSizeAdapter(props.behavior); 53 | Widget? _child = props.child == null 54 | ? null 55 | : YZDynamicCommon.buildWidget(props.child, context: context); 56 | 57 | GestureDetector _subwidget = GestureDetector( 58 | child: _child, 59 | onTap: () { 60 | super.triggerEvent(YZDynamicWidgetEventType.onClick); 61 | }, 62 | onLongPress: () { 63 | super.triggerEvent(YZDynamicWidgetEventType.onLongPress); 64 | }, 65 | behavior: _behavior, 66 | onTapDown: null, 67 | onTapUp: null, 68 | onTapCancel: null, 69 | onSecondaryTap: null, 70 | onSecondaryTapDown: null, 71 | onSecondaryTapUp: null, 72 | onSecondaryTapCancel: null, 73 | onTertiaryTapDown: null, 74 | onTertiaryTapUp: null, 75 | onTertiaryTapCancel: null, 76 | onDoubleTapDown: null, 77 | onDoubleTap: null, 78 | onDoubleTapCancel: null, 79 | onLongPressStart: null, 80 | onLongPressMoveUpdate: null, 81 | onLongPressUp: null, 82 | onLongPressEnd: null, 83 | onSecondaryLongPress: null, 84 | onSecondaryLongPressStart: null, 85 | onSecondaryLongPressMoveUpdate: null, 86 | onSecondaryLongPressUp: null, 87 | onSecondaryLongPressEnd: null, 88 | onVerticalDragDown: null, 89 | onVerticalDragStart: null, 90 | onVerticalDragUpdate: null, 91 | onVerticalDragEnd: null, 92 | onVerticalDragCancel: null, 93 | onHorizontalDragDown: null, 94 | onHorizontalDragStart: null, 95 | onHorizontalDragUpdate: null, 96 | onHorizontalDragEnd: null, 97 | onHorizontalDragCancel: null, 98 | onForcePressStart: null, 99 | onForcePressPeak: null, 100 | onForcePressUpdate: null, 101 | onForcePressEnd: null, 102 | onPanDown: null, 103 | onPanStart: null, 104 | onPanUpdate: null, 105 | onPanEnd: null, 106 | onPanCancel: null, 107 | onScaleStart: null, 108 | onScaleUpdate: null, 109 | onScaleEnd: null, 110 | excludeFromSemantics: false, 111 | dragStartBehavior: DragStartBehavior.start, 112 | ); 113 | 114 | //Deal with events / 处理事件 115 | _widget = super.buildWithEvents(_subwidget, super.config?.xEvents); 116 | 117 | return _widget; 118 | } 119 | 120 | @override 121 | void registerActions() {} 122 | } 123 | 124 | /// The props of GestureDetector config 125 | class YZGestureDetectorConfig { 126 | Map? child; 127 | String? behavior; 128 | 129 | YZGestureDetectorConfig({this.child, this.behavior}); 130 | 131 | YZGestureDetectorConfig.fromJson(Map? json) { 132 | json ??= {}; 133 | child = json['child']; 134 | behavior = json['behavior']; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /lib/widgets/model/widget_config.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-09-02 10:30:35 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-09-19 16:09:56 6 | **/ 7 | 8 | 9 | import '../../tools/action.dart'; 10 | 11 | class YZDynamicWidgetConfig { 12 | String? type; 13 | String? widget; 14 | Map? props; 15 | Map? xActions; 16 | String? xKey; 17 | List? xEvents; 18 | List? xData; 19 | Map? xCode; 20 | List? xRules; 21 | Map? xRef; 22 | String? isFormField; 23 | Map? xVar; 24 | YZXCondition? xCondition; 25 | YZDynamicWidgetLifecycle? state; 26 | List? children; //兼容web数据模型 27 | 28 | YZDynamicWidgetConfig({this.type, this.widget, this.props, this.xActions, this.xKey, this.xEvents, this.xData, this.xCode, this.xRules, this.xRef, this.isFormField, this.xVar, this.state, this.xCondition}); 29 | 30 | YZDynamicWidgetConfig.fromJson(Map? json) { 31 | json ??= {}; 32 | 33 | type = json['type']; 34 | widget = json['widget']; 35 | props = json['props']; 36 | if (json['xActions'] != null) { 37 | xActions = (json['xActions'] as Map).map( 38 | (key, value) => MapEntry(key, YZDynamicActionConfig.fromJson(value)) 39 | ); 40 | } 41 | xKey = json['xKey']; 42 | xEvents = json['xEvents']; 43 | xData = json['xData']; 44 | xCode = json['xCode']; 45 | xRules = json['xRules']; 46 | xRef = json['xRef']; 47 | isFormField = json['isFormField']; 48 | xVar = json['xVar']; 49 | state = json['state'] != null 50 | ? new YZDynamicWidgetLifecycle.fromJson(json['state']) 51 | : null; 52 | xCondition = json['xCondition'] != null 53 | ? new YZXCondition.fromJson(json['xCondition']) 54 | : null; 55 | } 56 | 57 | } 58 | 59 | class YZXCondition { 60 | YZRepeatChild? repeatChild; 61 | 62 | YZXCondition({this.repeatChild}); 63 | 64 | YZXCondition.fromJson(Map json) { 65 | repeatChild = json['repeatChild'] != null 66 | ? new YZRepeatChild.fromJson(json['repeatChild']) 67 | : null; 68 | } 69 | } 70 | 71 | class YZRepeatChild { 72 | String? data; 73 | String? item; 74 | 75 | YZRepeatChild({this.data, this.item}); 76 | 77 | YZRepeatChild.fromJson(Map json) { 78 | data = json['data']; 79 | item = json['item']; 80 | } 81 | } 82 | 83 | class YZDynamicWidgetLifecycle { 84 | List? beforeEntrance; 85 | List? initState; 86 | List? build; 87 | List? dispose; 88 | List? afterLeave; 89 | 90 | YZDynamicWidgetLifecycle( 91 | {this.beforeEntrance, 92 | this.initState, 93 | this.build, 94 | this.dispose, 95 | this.afterLeave}); 96 | 97 | YZDynamicWidgetLifecycle.fromJson(Map json) { 98 | if (json['beforeEntrance'] != null) { 99 | beforeEntrance = []; 100 | json['beforeEntrance'].forEach((v) { 101 | beforeEntrance!.add(new YZDynamicActionConfig.fromJson(v)); 102 | }); 103 | } 104 | if (json['initState'] != null) { 105 | initState = []; 106 | json['initState'].forEach((v) { 107 | initState!.add(new YZDynamicActionConfig.fromJson(v)); 108 | }); 109 | } 110 | if (json['build'] != null) { 111 | build = []; 112 | json['build'].forEach((v) { 113 | build!.add(new YZDynamicActionConfig.fromJson(v)); 114 | }); 115 | } 116 | if (json['dispose'] != null) { 117 | dispose = []; 118 | json['dispose'].forEach((v) { 119 | dispose!.add(new YZDynamicActionConfig.fromJson(v)); 120 | }); 121 | } 122 | if (json['afterLeave'] != null) { 123 | afterLeave = []; 124 | json['afterLeave'].forEach((v) { 125 | afterLeave!.add(new YZDynamicActionConfig.fromJson(v)); 126 | }); 127 | } 128 | } 129 | 130 | } -------------------------------------------------------------------------------- /lib/widgets/offstage.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Offstage 3 | * @Author: chenlijiao 4 | * @Date: 2021-03-16 14:38:38 5 | * @LastEditors: chenlijiao 6 | * @LastEditTime: 2021-03-18 11:31:12 7 | */ 8 | 9 | import 'package:flutter/material.dart'; 10 | import 'package:yz_flutter_dynamic/tools/common.dart'; 11 | 12 | import 'basic/handler.dart'; 13 | import 'basic/utils.dart'; 14 | import 'basic/widget.dart'; 15 | 16 | class YZOffstageHandler extends YZDynamicBasicWidgetHandler { 17 | @override 18 | String get widgetName => 'Offstage'; 19 | 20 | @override 21 | Widget build(Map json, 22 | {Key? key, BuildContext? buildContext}) { 23 | return _Builder(json, key: key); 24 | } 25 | } 26 | 27 | class _Builder extends YZDynamicBaseWidget { 28 | final Map json; 29 | 30 | _Builder(this.json, {Key? key}) : super(json, key: key); 31 | 32 | @override 33 | _BuilderState createState() => _BuilderState(); 34 | } 35 | 36 | class _BuilderState extends YZDynamicWidgetBasicState<_Builder> { 37 | @override 38 | void initState() { 39 | super.initState(); 40 | } 41 | 42 | @override 43 | Widget build(BuildContext context) { 44 | Widget _widget; 45 | 46 | //Deal with props / 处理控件属性 47 | YZOffstageConfig props = 48 | YZOffstageConfig.fromJson(super.config?.props ?? {}); 49 | bool? _offstage = YZDynamicWidgetUtils.boolAdapter(props.offstage, state: this); 50 | Widget? _child = props.child == null 51 | ? null 52 | : YZDynamicCommon.buildWidget(props.child, context: context); 53 | 54 | Offstage _subwidget = Offstage(offstage: _offstage ?? true, child: _child); 55 | 56 | //Deal with events / 处理事件 57 | _widget = super.buildWithEvents(_subwidget, super.config?.xEvents); 58 | 59 | return _widget; 60 | } 61 | 62 | @override 63 | void registerActions() { 64 | //Deal with action / 处理事件实现 65 | actionFunctions['setState'] = stateSetter; 66 | } 67 | 68 | void stateSetter(BuildContext? triggerContext, { 69 | Map? params, 70 | YZDynamicRequest? request, 71 | List? rules, 72 | Map? localVariables, 73 | State? state, 74 | }) { 75 | print('Execute xAction: ${this.runtimeType} setState'); 76 | if (mounted) { 77 | setState(() {}); 78 | } 79 | } 80 | } 81 | 82 | /// The props of Offstage config 83 | class YZOffstageConfig { 84 | String? offstage; 85 | Map? child; 86 | 87 | YZOffstageConfig({this.offstage, this.child}); 88 | 89 | YZOffstageConfig.fromJson(Map? json) { 90 | json ??= {}; 91 | offstage = json['offstage']; 92 | child = json['child']; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /lib/widgets/padding.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-11-03 11:25:41 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-11-19 10:11:28 6 | */ 7 | 8 | import 'dart:convert'; 9 | 10 | import 'package:flutter/material.dart'; 11 | import '../tools/common.dart'; 12 | import 'basic/utils.dart'; 13 | import 'basic/handler.dart'; 14 | import 'basic/widget.dart'; 15 | 16 | /// Padding handler 17 | class YZPaddingHandler extends YZDynamicBasicWidgetHandler { 18 | 19 | @override 20 | String get widgetName => 'Padding'; 21 | 22 | @override 23 | Widget build(Map json, {Key? key, BuildContext? buildContext}) { 24 | return _Builder(json, key:key); 25 | } 26 | 27 | } 28 | 29 | class _Builder extends YZDynamicBaseWidget { 30 | 31 | final Map json; 32 | 33 | _Builder(this.json, {Key? key}): super(json, key: key); 34 | 35 | @override 36 | _BuilderState createState() => _BuilderState(); 37 | } 38 | 39 | class _BuilderState extends YZDynamicWidgetBasicState<_Builder> { 40 | 41 | @override 42 | void initState() { 43 | super.initState(); 44 | } 45 | 46 | @override 47 | Widget build(BuildContext context) { 48 | Widget _widget; 49 | 50 | //Deal with props / 处理控件属性 51 | YZPaddingConfig props = YZPaddingConfig.fromJson(super.config?.props ?? {}); 52 | EdgeInsets? _padding = YZDynamicWidgetUtils.edgeInsetAdapter(props.padding); 53 | Widget? _child = props.child == null ? null : YZDynamicCommon.buildWidget(props.child, context: context); 54 | 55 | Padding _subwidget = Padding( 56 | padding: _padding!, 57 | child: _child, 58 | ); 59 | 60 | //Deal with events / 处理事件 61 | _widget = super.buildWithEvents(_subwidget, super.config?.xEvents); 62 | 63 | return _widget; 64 | } 65 | 66 | @override 67 | void registerActions() { 68 | //Deal with action / 处理事件实现 69 | } 70 | 71 | } 72 | 73 | /// The props of Padding config 74 | class YZPaddingConfig { 75 | List? padding; 76 | Map? child; 77 | 78 | YZPaddingConfig( 79 | {this.padding, 80 | this.child}); 81 | 82 | YZPaddingConfig.fromJson(Map? json) { 83 | json ??= {}; 84 | padding = json['padding'] == null ? null : jsonDecode(json['padding']); 85 | child = json['child']; 86 | } 87 | } -------------------------------------------------------------------------------- /lib/widgets/positioned.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Positioned 3 | * @Author: chenlijiao 4 | * @Date: 2021-03-15 16:02:24 5 | * @LastEditors: chenlijiao 6 | * @LastEditTime: 2021-03-19 11:25:20 7 | */ 8 | 9 | import 'package:flutter/material.dart'; 10 | import 'package:yz_flutter_dynamic/tools/common.dart'; 11 | import 'basic/handler.dart'; 12 | import 'basic/utils.dart'; 13 | import 'basic/widget.dart'; 14 | 15 | class YZPositionedHandler extends YZDynamicBasicWidgetHandler { 16 | @override 17 | String get widgetName => 'Positioned'; 18 | 19 | @override 20 | Widget build(Map json, 21 | {Key? key, BuildContext? buildContext}) { 22 | return _Builder(json, key: key); 23 | } 24 | } 25 | 26 | class _Builder extends YZDynamicBaseWidget { 27 | final Map json; 28 | 29 | _Builder(this.json, {Key? key}) : super(json, key: key); 30 | 31 | @override 32 | _BuilderState createState() => _BuilderState(); 33 | } 34 | 35 | class _BuilderState extends YZDynamicWidgetBasicState<_Builder> { 36 | //Deal with props / 处理控件属性 37 | late YZPositionedConfig props; 38 | 39 | double? _left; 40 | double? _top; 41 | double? _right; 42 | double? _bottom; 43 | double? _width; 44 | double? _height; 45 | Widget? _child; 46 | 47 | @override 48 | void initState() { 49 | super.initState(); 50 | 51 | //Deal with props / 处理控件属性 52 | props = YZPositionedConfig.fromJson(super.config?.props ?? {}); 53 | 54 | _left = YZDynamicWidgetUtils.doubleAdapter(props.left); 55 | _top = YZDynamicWidgetUtils.doubleAdapter(props.top); 56 | _right = YZDynamicWidgetUtils.doubleAdapter(props.right); 57 | _bottom = YZDynamicWidgetUtils.doubleAdapter(props.bottom); 58 | _width = YZDynamicWidgetUtils.doubleAdapter(props.width); 59 | _height = YZDynamicWidgetUtils.doubleAdapter(props.height); 60 | 61 | _child = props.child == null 62 | ? null 63 | : YZDynamicCommon.buildWidget(props.child, context: context); 64 | } 65 | 66 | @override 67 | Widget build(BuildContext context) { 68 | Widget _widget; 69 | 70 | Positioned _subwidget = Positioned( 71 | left: _left, 72 | top: _top, 73 | right: _right, 74 | bottom: _bottom, 75 | width: _width, 76 | height: _height, 77 | child: _child!, 78 | ); 79 | 80 | //Deal with events / 处理事件 81 | _widget = super.buildWithEvents(_subwidget, super.config?.xEvents); 82 | 83 | return _widget; 84 | } 85 | 86 | @override 87 | void registerActions() { 88 | //Deal with action / 处理事件实现 89 | } 90 | 91 | } 92 | 93 | /// The props of Positioned config 94 | class YZPositionedConfig { 95 | String? left; 96 | String? top; 97 | String? right; 98 | String? bottom; 99 | String? width; 100 | String? height; 101 | Map? child; 102 | 103 | YZPositionedConfig( 104 | {this.left, 105 | this.top, 106 | this.bottom, 107 | this.right, 108 | this.width, 109 | this.height, 110 | this.child}); 111 | 112 | YZPositionedConfig.fromJson(Map? json) { 113 | json ??= {}; 114 | left = json['left']; 115 | right = json['right']; 116 | top = json['top']; 117 | bottom = json['bottom']; 118 | width = json['width']; 119 | height = json['height']; 120 | child = json['child']; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /lib/widgets/radio.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Radio 3 | * @Author: chenlijiao 4 | * @Date: 2021-02-24 16:44:58 5 | * @LastEditors: chenlijiao 6 | * @LastEditTime: 2021-03-18 18:20:33 7 | */ 8 | 9 | import 'package:flutter/material.dart'; 10 | import 'package:yz_flutter_dynamic/tools/common.dart'; 11 | import 'basic/event.dart'; 12 | import 'basic/handler.dart'; 13 | import 'basic/utils.dart'; 14 | import 'basic/widget.dart'; 15 | 16 | class YZRadioHandler extends YZDynamicBasicWidgetHandler { 17 | @override 18 | Widget build(Map json, 19 | {Key? key, BuildContext? buildContext}) { 20 | return _Builder(json, key: key); 21 | } 22 | 23 | @override 24 | String get widgetName => 'Radio'; 25 | } 26 | 27 | class _Builder extends YZDynamicBaseWidget { 28 | final Map json; 29 | 30 | _Builder(this.json, {Key? key}) : super(json, key: key); 31 | 32 | @override 33 | _BuilderState createState() => _BuilderState(); 34 | } 35 | 36 | class _BuilderState extends YZDynamicWidgetBasicState<_Builder> { 37 | //Deal with props / 处理控件属性 38 | late YZRadioConfig props; 39 | 40 | String? _value; 41 | String? _groupValue; 42 | bool? _toggleable; 43 | Color? _activeColor; 44 | Color? _focusColor; 45 | Color? _hoverColor; 46 | MaterialTapTargetSize? _materialTapTargetSize; 47 | 48 | @override 49 | void initState() { 50 | super.initState(); 51 | 52 | //Deal with props / 处理控件属性 53 | props = YZRadioConfig.fromJson(super.config?.props ?? {}); 54 | _value = props.value; 55 | _groupValue = props.groupValue; 56 | _toggleable = YZDynamicWidgetUtils.boolAdapter(props.toggleable); 57 | _activeColor = YZDynamicWidgetUtils.colorAdapter(props.activeColor); 58 | _focusColor = YZDynamicWidgetUtils.colorAdapter(props.focusColor); 59 | _hoverColor = YZDynamicWidgetUtils.colorAdapter(props.hoverColor); 60 | _materialTapTargetSize = YZDynamicWidgetUtils.materialTapTargetSizeAdapter( 61 | props.materialTapTargetSize); 62 | } 63 | 64 | @override 65 | Widget build(BuildContext context) { 66 | Radio _widget = Radio( 67 | value: _value, 68 | groupValue: _groupValue, 69 | activeColor: _activeColor, 70 | mouseCursor: null, 71 | toggleable: _toggleable ?? false, 72 | focusColor: _focusColor, 73 | hoverColor: _hoverColor, 74 | visualDensity: null, 75 | focusNode: null, 76 | autofocus: false, 77 | materialTapTargetSize: _materialTapTargetSize, 78 | onChanged: (value) { 79 | this.value = value.toString(); 80 | _value = _groupValue; 81 | setState(() {}); 82 | super.triggerEvent(YZDynamicWidgetEventType.onValueChanged); 83 | }, 84 | ); 85 | 86 | return _widget; 87 | } 88 | 89 | @override 90 | void registerActions() { 91 | //Deal with action / 处理事件实现 92 | actionFunctions['setState'] = stateSetter; 93 | } 94 | 95 | void stateSetter(BuildContext? triggerContext, { 96 | Map? params, 97 | YZDynamicRequest? request, 98 | List? rules, 99 | Map? localVariables, 100 | State? state, 101 | }) { 102 | print('Execute xAction: ${this.runtimeType} setState'); 103 | if (mounted) { 104 | setState(() {}); 105 | } 106 | } 107 | } 108 | 109 | /// The props of Radio config 110 | class YZRadioConfig { 111 | String? value; 112 | String? groupValue; 113 | String? toggleable; 114 | String? activeColor; 115 | String? focusColor; 116 | String? hoverColor; 117 | String? materialTapTargetSize; 118 | 119 | YZRadioConfig( 120 | {this.value, 121 | this.groupValue, 122 | this.toggleable, 123 | this.activeColor, 124 | this.focusColor, 125 | this.hoverColor, 126 | this.materialTapTargetSize}); 127 | 128 | YZRadioConfig.fromJson(Map? json) { 129 | json ??= {}; 130 | value = json['value']; 131 | groupValue = json['groupValue']; 132 | toggleable = json['toggleable']; 133 | activeColor = json['activeColor']; 134 | focusColor = json['focusColor']; 135 | hoverColor = json['hoverColor']; 136 | materialTapTargetSize = json['materialTapTargetSize']; 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /lib/widgets/row.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-11-02 22:30:24 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-11-19 10:11:30 6 | */ 7 | 8 | import 'package:flutter/material.dart'; 9 | import '../tools/common.dart'; 10 | import 'basic/utils.dart'; 11 | import 'basic/handler.dart'; 12 | import 'basic/widget.dart'; 13 | 14 | /// Row handler 15 | class YZRowHandler extends YZDynamicBasicWidgetHandler { 16 | 17 | @override 18 | String get widgetName => 'Row'; 19 | 20 | @override 21 | Widget build(Map json, {Key? key, BuildContext? buildContext}) { 22 | return _Builder(json, key:key); 23 | } 24 | 25 | } 26 | 27 | class _Builder extends YZDynamicBaseWidget { 28 | 29 | final Map json; 30 | 31 | _Builder(this.json, {Key? key}): super(json, key: key); 32 | 33 | @override 34 | _BuilderState createState() => _BuilderState(); 35 | } 36 | 37 | class _BuilderState extends YZDynamicWidgetBasicState<_Builder> { 38 | 39 | @override 40 | void initState() { 41 | super.initState(); 42 | } 43 | 44 | @override 45 | Widget build(BuildContext context) { 46 | Widget _widget; 47 | 48 | //Deal with props / 处理控件属性 49 | YZRowConfig props = YZRowConfig.fromJson(super.config?.props ?? {}); 50 | MainAxisAlignment? _mainAxisAlignment = YZDynamicWidgetUtils.mainAxisAlignmentAdapter(props.mainAxisAlignment); 51 | MainAxisSize? _mainAxisSize = YZDynamicWidgetUtils.mainAxisSizeAdapter(props.mainAxisSize); 52 | CrossAxisAlignment? _crossAxisAlignment = YZDynamicWidgetUtils.crossAxisAlignmentAdapter(props.crossAxisAlignment); 53 | TextDirection? _textDirection = YZDynamicWidgetUtils.textDirectionAdapter(props.textDirection); 54 | VerticalDirection? _verticalDirection = YZDynamicWidgetUtils.verticalDirectionAdapter(props.verticalDirection); 55 | TextBaseline? _textBaseline = YZDynamicWidgetUtils.textBaselineAdapter(props.verticalDirection); 56 | late List _children; 57 | if (props.children != null) { 58 | _children = []; 59 | props.children?.forEach((e) { 60 | Widget? _child = YZDynamicCommon.buildWidget(e, context: context); 61 | if (_child == null)return; 62 | _children.add(_child); 63 | }); 64 | } 65 | 66 | Row _subwidget = Row( 67 | mainAxisAlignment: _mainAxisAlignment ?? MainAxisAlignment.start, 68 | mainAxisSize: _mainAxisSize ?? MainAxisSize.max, 69 | crossAxisAlignment: _crossAxisAlignment ?? CrossAxisAlignment.center, 70 | textDirection: _textDirection, 71 | verticalDirection: _verticalDirection ?? VerticalDirection.down, 72 | textBaseline: _textBaseline ?? TextBaseline.alphabetic, 73 | children: _children, 74 | ); 75 | 76 | //Deal with events / 处理事件 77 | _widget = super.buildWithEvents(_subwidget, super.config?.xEvents); 78 | 79 | return _widget; 80 | } 81 | 82 | @override 83 | void registerActions() { 84 | //Deal with action / 处理事件实现 85 | } 86 | 87 | } 88 | 89 | /// The props of Row config 90 | class YZRowConfig { 91 | String? mainAxisAlignment; 92 | String? mainAxisSize; 93 | String? crossAxisAlignment; 94 | String? textDirection; 95 | String? verticalDirection; 96 | String? textBaseline; 97 | List? children; 98 | 99 | YZRowConfig( 100 | {this.mainAxisAlignment, 101 | this.mainAxisSize, 102 | this.crossAxisAlignment, 103 | this.textDirection, 104 | this.verticalDirection, 105 | this.textBaseline, 106 | this.children}); 107 | 108 | YZRowConfig.fromJson(Map? json) { 109 | json ??= {}; 110 | mainAxisAlignment = json['mainAxisAlignment']; 111 | mainAxisSize = json['mainAxisSize']; 112 | crossAxisAlignment = json['crossAxisAlignment']; 113 | textDirection = json['textDirection']; 114 | verticalDirection = json['verticalDirection']; 115 | textBaseline = json['textBaseline']; 116 | if (json['children'] != null) { 117 | children = []; 118 | json['children'].forEach((v) { 119 | children!.add(v); 120 | }); 121 | } 122 | } 123 | 124 | } -------------------------------------------------------------------------------- /lib/widgets/safe_area.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-11-03 11:17:48 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-11-03 11:29:51 6 | */ 7 | 8 | import 'package:flutter/material.dart'; 9 | import '../tools/common.dart'; 10 | import 'basic/utils.dart'; 11 | import 'basic/handler.dart'; 12 | import 'basic/widget.dart'; 13 | 14 | /// SafeArea handler 15 | class YZSafeAreaHandler extends YZDynamicBasicWidgetHandler { 16 | 17 | @override 18 | String get widgetName => 'SafeArea'; 19 | 20 | @override 21 | Widget build(Map json, {Key? key, BuildContext? buildContext}) { 22 | return _Builder(json, key:key); 23 | } 24 | 25 | } 26 | 27 | class _Builder extends YZDynamicBaseWidget { 28 | 29 | final Map json; 30 | 31 | _Builder(this.json, {Key? key}): super(json, key: key); 32 | 33 | @override 34 | _BuilderState createState() => _BuilderState(); 35 | } 36 | 37 | class _BuilderState extends YZDynamicWidgetBasicState<_Builder> { 38 | 39 | @override 40 | void initState() { 41 | super.initState(); 42 | } 43 | 44 | @override 45 | Widget build(BuildContext context) { 46 | Widget _widget; 47 | 48 | //Deal with props / 处理控件属性 49 | YZSafeAreaConfig props = YZSafeAreaConfig.fromJson(super.config?.props ?? {}); 50 | bool? _left = YZDynamicWidgetUtils.boolAdapter(props.left); 51 | bool? _top = YZDynamicWidgetUtils.boolAdapter(props.top); 52 | bool? _bottom = YZDynamicWidgetUtils.boolAdapter(props.bottom); 53 | bool? _right = YZDynamicWidgetUtils.boolAdapter(props.right); 54 | EdgeInsets? _minimum = YZDynamicWidgetUtils.edgeInsetAdapter(props.minimum); 55 | bool? _maintainBottomViewPadding = YZDynamicWidgetUtils.boolAdapter(props.maintainBottomViewPadding); 56 | Widget? _child = props.child == null ? null : YZDynamicCommon.buildWidget(props.child, context: context); 57 | 58 | SafeArea _subwidget = SafeArea( 59 | left: _left ?? true, 60 | top: _top ?? true, 61 | bottom: _bottom ?? true, 62 | right: _right ?? true, 63 | minimum: _minimum ?? EdgeInsets.zero, 64 | maintainBottomViewPadding: _maintainBottomViewPadding ?? false, 65 | child: _child!, 66 | ); 67 | 68 | //Deal with events / 处理事件 69 | _widget = super.buildWithEvents(_subwidget, super.config?.xEvents); 70 | 71 | return _widget; 72 | } 73 | 74 | @override 75 | void registerActions() { 76 | } 77 | 78 | } 79 | 80 | /// The props of SafeArea config 81 | class YZSafeAreaConfig { 82 | String? left; 83 | String? top; 84 | String? bottom; 85 | String? right; 86 | String? minimum; 87 | String? maintainBottomViewPadding; 88 | Map? child; 89 | 90 | YZSafeAreaConfig( 91 | {this.left, 92 | this.top, 93 | this.bottom, 94 | this.right, 95 | this.minimum, 96 | this.maintainBottomViewPadding, 97 | this.child}); 98 | 99 | YZSafeAreaConfig.fromJson(Map? json) { 100 | json ??= {}; 101 | left = json['left']; 102 | top = json['top']; 103 | bottom = json['bottom']; 104 | right = json['right']; 105 | minimum = json['minimum']; 106 | maintainBottomViewPadding = json['maintainBottomViewPadding']; 107 | child = json['child']; 108 | } 109 | 110 | } -------------------------------------------------------------------------------- /lib/widgets/scaffold.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-11-02 22:26:21 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-11-02 22:26:21 6 | */ 7 | 8 | import 'package:flutter/gestures.dart'; 9 | import 'package:flutter/material.dart'; 10 | import '../tools/common.dart'; 11 | import 'basic/handler.dart'; 12 | import 'basic/widget.dart'; 13 | 14 | /// Scaffold handler 15 | class YZScaffoldHandler extends YZDynamicBasicWidgetHandler { 16 | 17 | @override 18 | String get widgetName => 'Scaffold'; 19 | 20 | @override 21 | Widget build(Map json, {Key? key, BuildContext? buildContext}) { 22 | return _Builder(json, key:key); 23 | } 24 | 25 | } 26 | 27 | class _Builder extends YZDynamicBaseWidget { 28 | 29 | final Map json; 30 | 31 | _Builder(this.json, {Key? key}): super(json, key: key); 32 | 33 | @override 34 | _BuilderState createState() => _BuilderState(); 35 | } 36 | 37 | class _BuilderState extends YZDynamicWidgetBasicState<_Builder> { 38 | 39 | //Deal with props / 处理控件属性 40 | late YZScaffoldConfig props; 41 | 42 | PreferredSizeWidget? _appBar; 43 | Widget? _body; 44 | 45 | @override 46 | void initState() { 47 | super.initState(); 48 | 49 | props = YZScaffoldConfig.fromJson(super.config?.props ?? {}); 50 | _appBar = YZDynamicCommon.buildWidget(props.appBar, context: context) as PreferredSizeWidget; 51 | _body = YZDynamicCommon.buildWidget(props.body, context: context); 52 | 53 | } 54 | 55 | @override 56 | Widget build(BuildContext context) { 57 | Widget _widget; 58 | 59 | _widget = Scaffold( 60 | appBar: _appBar, 61 | body: _body, 62 | floatingActionButton: null, 63 | floatingActionButtonLocation: null, 64 | floatingActionButtonAnimator: null, 65 | persistentFooterButtons: null, 66 | drawer: null, 67 | endDrawer: null, 68 | bottomNavigationBar: null, 69 | bottomSheet: null, 70 | backgroundColor: null, 71 | resizeToAvoidBottomInset: null, 72 | primary: true, 73 | drawerDragStartBehavior: DragStartBehavior.start, 74 | extendBody: false, 75 | extendBodyBehindAppBar: false, 76 | drawerScrimColor: null, 77 | drawerEdgeDragWidth: null, 78 | drawerEnableOpenDragGesture: true, 79 | endDrawerEnableOpenDragGesture: true, 80 | ); 81 | 82 | return _widget; 83 | } 84 | 85 | @override 86 | void registerActions() { 87 | } 88 | 89 | } 90 | 91 | /// The props of Scaffold config 92 | class YZScaffoldConfig { 93 | Map? appBar; 94 | Map? body; 95 | 96 | YZScaffoldConfig({ 97 | this.appBar, 98 | this.body, 99 | }); 100 | 101 | YZScaffoldConfig.fromJson(Map? json) { 102 | json ??= {}; 103 | appBar = json['appBar']; 104 | body = json['body']; 105 | } 106 | 107 | } -------------------------------------------------------------------------------- /lib/widgets/scroll_view.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-11-02 22:29:51 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-11-03 12:04:03 6 | */ 7 | 8 | import 'package:flutter/gestures.dart'; 9 | import 'package:flutter/material.dart'; 10 | import '../tools/common.dart'; 11 | import 'basic/utils.dart'; 12 | import 'basic/handler.dart'; 13 | import 'basic/widget.dart'; 14 | 15 | /// SingleChildScrollView handler 16 | class YZSingleChildScrollViewHandler extends YZDynamicBasicWidgetHandler { 17 | 18 | @override 19 | String get widgetName => 'SingleChildScrollView'; 20 | 21 | @override 22 | Widget build(Map json, {Key? key, BuildContext? buildContext}) { 23 | return _Builder(json, key:key); 24 | } 25 | 26 | } 27 | 28 | class _Builder extends YZDynamicBaseWidget { 29 | 30 | final Map json; 31 | 32 | _Builder(this.json, {Key? key}): super(json, key: key); 33 | 34 | @override 35 | _BuilderState createState() => _BuilderState(); 36 | } 37 | 38 | class _BuilderState extends YZDynamicWidgetBasicState<_Builder> { 39 | 40 | @override 41 | void initState() { 42 | super.initState(); 43 | } 44 | 45 | @override 46 | Widget build(BuildContext context) { 47 | Widget _widget; 48 | 49 | //Deal with props / 处理控件属性 50 | YZSingleChildScrollViewConfig props = YZSingleChildScrollViewConfig.fromJson(super.config?.props ?? {}); 51 | Axis? _scrollDirection = YZDynamicWidgetUtils.axisAdapter(props.scrollDirection); 52 | bool? _reverse = YZDynamicWidgetUtils.boolAdapter(props.reverse); 53 | bool? _primary = YZDynamicWidgetUtils.boolAdapter(props.primary); 54 | ScrollController _controller = ScrollController(); 55 | DragStartBehavior? _dragStartBehavior = dragStartBehaviorAdapter(props.dragStartBehavior); 56 | EdgeInsets? _padding = YZDynamicWidgetUtils.edgeInsetAdapter(props.padding); 57 | Clip? _clipBehavior = YZDynamicWidgetUtils.clipBehaviorAdapter(props.clipBehavior); 58 | String? _restorationId = props.restorationId; 59 | Widget? _child = props.child == null ? null : YZDynamicCommon.buildWidget(props.child, context: context); 60 | 61 | SingleChildScrollView _subwidget = SingleChildScrollView( 62 | scrollDirection: _scrollDirection ?? Axis.vertical, 63 | reverse: _reverse ?? false, 64 | padding: _padding, 65 | primary: _primary, 66 | physics: null, 67 | controller: _controller, 68 | dragStartBehavior: _dragStartBehavior ?? DragStartBehavior.start, 69 | clipBehavior: _clipBehavior ?? Clip.hardEdge, 70 | restorationId: _restorationId, 71 | child: _child, 72 | ); 73 | 74 | //Deal with events / 处理事件 75 | _widget = super.buildWithEvents(_subwidget, super.config?.xEvents); 76 | 77 | return _widget; 78 | } 79 | 80 | @override 81 | void registerActions() { 82 | } 83 | 84 | ///adapt dsl 85 | static DragStartBehavior? dragStartBehaviorAdapter(String? str){ 86 | 87 | DragStartBehavior? _ret; 88 | switch (str) { 89 | case 'down': 90 | _ret = DragStartBehavior.down; 91 | break; 92 | case 'start': 93 | _ret = DragStartBehavior.start; 94 | break; 95 | default: 96 | 97 | } 98 | 99 | return _ret; 100 | } 101 | 102 | } 103 | 104 | /// The props of SingleChildScrollView config 105 | class YZSingleChildScrollViewConfig { 106 | String? scrollDirection; 107 | String? reverse; 108 | String? padding; 109 | String? primary; 110 | String? physics; 111 | String? controller; 112 | String? dragStartBehavior; 113 | String? clipBehavior; 114 | String? restorationId; 115 | Map? child; 116 | 117 | YZSingleChildScrollViewConfig( 118 | {this.scrollDirection, 119 | this.reverse, 120 | this.padding, 121 | this.primary, 122 | this.physics, 123 | this.controller, 124 | this.dragStartBehavior, 125 | this.clipBehavior, 126 | this.restorationId, 127 | this.child}); 128 | 129 | YZSingleChildScrollViewConfig.fromJson(Map? json) { 130 | json ??= {}; 131 | scrollDirection = json['scrollDirection']; 132 | reverse = json['reverse']; 133 | padding = json['padding']; 134 | primary = json['primary']; 135 | physics = json['physics']; 136 | controller = json['controller']; 137 | dragStartBehavior = json['dragStartBehavior']; 138 | clipBehavior = json['clipBehavior']; 139 | restorationId = json['restorationId']; 140 | child = json['child']; 141 | } 142 | 143 | } -------------------------------------------------------------------------------- /lib/widgets/simple_dialog.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-11-13 08:48:55 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-11-13 08:48:55 6 | */ -------------------------------------------------------------------------------- /lib/widgets/stack.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: stack 3 | * @Author: chenlijiao 4 | * @Date: 2021-03-15 15:37:07 5 | * @LastEditors: chenlijiao 6 | * @LastEditTime: 2021-03-18 17:50:41 7 | */ 8 | 9 | import 'package:flutter/material.dart'; 10 | import 'package:yz_flutter_dynamic/tools/common.dart'; 11 | 12 | import 'basic/handler.dart'; 13 | import 'basic/utils.dart'; 14 | import 'basic/widget.dart'; 15 | 16 | class YZStackHandler extends YZDynamicBasicWidgetHandler { 17 | @override 18 | String get widgetName => 'Stack'; 19 | 20 | @override 21 | Widget build(Map json, 22 | {Key? key, BuildContext? buildContext}) { 23 | return _Builder(json, key: key); 24 | } 25 | } 26 | 27 | class _Builder extends YZDynamicBaseWidget { 28 | final Map json; 29 | 30 | _Builder(this.json, {Key? key}) : super(json, key: key); 31 | 32 | @override 33 | _BuilderState createState() => _BuilderState(); 34 | } 35 | 36 | class _BuilderState extends YZDynamicWidgetBasicState<_Builder> { 37 | @override 38 | void initState() { 39 | super.initState(); 40 | } 41 | 42 | @override 43 | Widget build(BuildContext context) { 44 | Widget _widget; 45 | 46 | //Deal with props / 处理控件属性 47 | YZStackConfig props = YZStackConfig.fromJson(super.config?.props ?? {}); 48 | 49 | AlignmentGeometry? _alignment = 50 | YZDynamicWidgetUtils.alignmentAdapter(props.alignment); 51 | TextDirection? _textDirection = 52 | YZDynamicWidgetUtils.textDirectionAdapter(props.textDirection); 53 | StackFit? _fit = YZDynamicWidgetUtils.stackFitAdapter(props.fit); 54 | late List _children; 55 | if (props.children != null) { 56 | _children = []; 57 | props.children?.forEach((e) { 58 | Widget? _child = YZDynamicCommon.buildWidget(e, context: context); 59 | if (_child == null) return; 60 | _children.add(_child); 61 | }); 62 | } 63 | 64 | Stack _subwidget = Stack( 65 | alignment: _alignment ?? AlignmentDirectional.topStart, 66 | textDirection: _textDirection, 67 | fit: _fit ?? StackFit.loose, 68 | clipBehavior: Clip.hardEdge, 69 | children: _children, 70 | ); 71 | 72 | //Deal with events / 处理事件 73 | _widget = super.buildWithEvents(_subwidget, super.config?.xEvents); 74 | 75 | return _widget; 76 | } 77 | 78 | @override 79 | void registerActions() { 80 | //Deal with action / 处理事件实现 81 | } 82 | 83 | } 84 | 85 | /// The props of Stack config 86 | class YZStackConfig { 87 | String? alignment; 88 | String? textDirection; 89 | String? fit; 90 | String? overflow; 91 | List? children; 92 | 93 | YZStackConfig( 94 | {this.alignment, 95 | this.textDirection, 96 | this.fit, 97 | this.overflow, 98 | this.children}); 99 | 100 | YZStackConfig.fromJson(Map? json) { 101 | json ??= {}; 102 | alignment = json['alignment']; 103 | textDirection = json['textDirection']; 104 | fit = json['fit']; 105 | overflow = json['overflow']; 106 | if (json['children'] != null) { 107 | children = []; 108 | json['children'].forEach((v) { 109 | children!.add(v); 110 | }); 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /lib/widgets/statefulwidget.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-09-02 11:21:35 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-11-18 11:54:01 6 | **/ 7 | 8 | import 'package:flutter/material.dart'; 9 | import '../tools/common.dart'; 10 | import 'basic/handler.dart'; 11 | import 'basic/widget.dart'; 12 | 13 | /// StatefulWidget handler 14 | class YZStatefulWidgetHandler extends YZDynamicBasicWidgetHandler { 15 | 16 | @override 17 | String get widgetName => 'StatefulWidget'; 18 | 19 | @override 20 | Widget build(Map json, {Key? key, BuildContext? buildContext}) { 21 | return _Builder(json, key:key); 22 | } 23 | 24 | } 25 | 26 | class _Builder extends YZDynamicBaseWidget { 27 | 28 | final Map json; 29 | 30 | _Builder(this.json, {Key? key}): super(json, key: key); 31 | 32 | @override 33 | _BuilderState createState() => _BuilderState(); 34 | } 35 | 36 | class _BuilderState extends YZDynamicWidgetBasicState<_Builder> { 37 | 38 | //Deal with props / 处理控件属性 39 | late YZStatefulWidgetConfig props; 40 | 41 | @override 42 | void initState() { 43 | super.initState(); 44 | 45 | //Deal with props / 处理控件属性 46 | props = YZStatefulWidgetConfig.fromJson(super.config?.props ?? {}); 47 | } 48 | 49 | @override 50 | Widget build(BuildContext context) { 51 | 52 | Widget _build = props.build == null ? SizedBox() : YZDynamicCommon.buildWidget(props.build, context: context)!; 53 | return _build; 54 | 55 | } 56 | 57 | @override 58 | void registerActions() { 59 | //Deal with action / 处理事件实现 60 | } 61 | 62 | } 63 | 64 | /// The props of StatefulWidget config 65 | class YZStatefulWidgetConfig { 66 | Map? build; 67 | 68 | YZStatefulWidgetConfig( 69 | {this.build 70 | }); 71 | 72 | YZStatefulWidgetConfig.fromJson(Map? json) { 73 | json ??= {}; 74 | build = json['build']; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /lib/widgets/statelesswidget.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: yz.yujingzhou 3 | * @Date: 2020-09-02 11:21:35 4 | * @Last Modified by: yz.yujingzhou 5 | * @Last Modified time: 2020-11-18 11:54:01 6 | **/ 7 | 8 | import 'package:flutter/material.dart'; 9 | import '../tools/common.dart'; 10 | import 'basic/handler.dart'; 11 | import 'model/widget_config.dart'; 12 | 13 | /// StatelessWidget handler 14 | class YZStatelessWidgetHandler extends YZDynamicBasicWidgetHandler { 15 | 16 | @override 17 | String get widgetName => 'StatelessWidget'; 18 | 19 | @override 20 | Widget build(Map json, {Key? key, BuildContext? buildContext}) { 21 | return _Builder(json, key:key); 22 | } 23 | 24 | } 25 | 26 | class _Builder extends StatelessWidget { 27 | 28 | final Map json; 29 | const _Builder(this.json, {Key? key}) : super(key: key); 30 | 31 | @override 32 | Widget build(BuildContext context) { 33 | //Deal with props / 处理控件属性 34 | YZDynamicWidgetConfig config = YZDynamicWidgetConfig.fromJson(json); 35 | YZStatelessWidgetConfig props = YZStatelessWidgetConfig.fromJson(config.props ?? {}); 36 | Widget _build = props.build == null ? SizedBox() : YZDynamicCommon.buildWidget(props.build, context: context)!; 37 | return _build; 38 | } 39 | } 40 | 41 | /// The props of StatelessWidget config 42 | class YZStatelessWidgetConfig { 43 | Map? build; 44 | 45 | YZStatelessWidgetConfig( 46 | {this.build 47 | }); 48 | 49 | YZStatelessWidgetConfig.fromJson(Map? json) { 50 | json ??= {}; 51 | build = json['build']; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /lib/widgets/wrap.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: Wrap 3 | * @Author: chenlijiao 4 | * @Date: 2021-03-15 11:27:51 5 | * @LastEditors: chenlijiao 6 | * @LastEditTime: 2021-03-18 17:53:22 7 | */ 8 | 9 | import 'package:flutter/material.dart'; 10 | import 'package:yz_flutter_dynamic/tools/common.dart'; 11 | import 'basic/handler.dart'; 12 | import 'basic/utils.dart'; 13 | import 'basic/widget.dart'; 14 | 15 | class YZWrapHandler extends YZDynamicBasicWidgetHandler { 16 | @override 17 | String get widgetName => 'Wrap'; 18 | 19 | @override 20 | Widget build(Map json, 21 | {Key? key, BuildContext? buildContext}) { 22 | return _Builder(json, key: key); 23 | } 24 | } 25 | 26 | class _Builder extends YZDynamicBaseWidget { 27 | final Map json; 28 | 29 | _Builder(this.json, {Key? key}) : super(json, key: key); 30 | 31 | @override 32 | _BuilderState createState() => _BuilderState(); 33 | } 34 | 35 | class _BuilderState extends YZDynamicWidgetBasicState<_Builder> { 36 | @override 37 | void initState() { 38 | super.initState(); 39 | } 40 | 41 | @override 42 | Widget build(BuildContext context) { 43 | Widget _widget; 44 | 45 | //Deal with props / 处理控件属性 46 | YZWrapConfig props = YZWrapConfig.fromJson(super.config?.props ?? {}); 47 | Axis? _direction = YZDynamicWidgetUtils.axisAdapter(props.direction); 48 | WrapAlignment? _alignment = 49 | YZDynamicWidgetUtils.wrapAlignmentAdapter(props.alignment); 50 | double? _spacing = YZDynamicWidgetUtils.doubleAdapter(props.spacing); 51 | WrapAlignment? _runAlignment = 52 | YZDynamicWidgetUtils.wrapAlignmentAdapter(props.runAlignment); 53 | double? _runSpacing = 54 | YZDynamicWidgetUtils.doubleAdapter(props.runAlignment); 55 | WrapCrossAlignment? _crossAxisAlignment = 56 | YZDynamicWidgetUtils.wrapCrossAlignmentAdapter( 57 | props.crossAxisAlignment); 58 | TextDirection? _textDirection = 59 | YZDynamicWidgetUtils.textDirectionAdapter(props.textDirection); 60 | VerticalDirection? _verticalDirection = 61 | YZDynamicWidgetUtils.verticalDirectionAdapter(props.verticalDirection); 62 | late List _children; 63 | if (props.children != null) { 64 | _children = []; 65 | props.children?.forEach((e) { 66 | Widget? _child = YZDynamicCommon.buildWidget(e, context: context); 67 | if (_child == null) return; 68 | _children.add(_child); 69 | }); 70 | } 71 | 72 | Wrap _subwidget = Wrap( 73 | direction: _direction ?? Axis.horizontal, 74 | alignment: _alignment ?? WrapAlignment.start, 75 | spacing: _spacing ?? 0, 76 | runAlignment: _runAlignment ?? WrapAlignment.start, 77 | runSpacing: _runSpacing ?? 0, 78 | crossAxisAlignment: _crossAxisAlignment ?? WrapCrossAlignment.center, 79 | textDirection: _textDirection, 80 | verticalDirection: _verticalDirection ?? VerticalDirection.down, 81 | clipBehavior: Clip.hardEdge, 82 | children: _children, 83 | ); 84 | 85 | //Deal with events / 处理事件 86 | _widget = super.buildWithEvents(_subwidget, super.config?.xEvents); 87 | 88 | return _widget; 89 | } 90 | 91 | @override 92 | void registerActions() { 93 | //Deal with action / 处理事件实现 94 | } 95 | 96 | } 97 | 98 | /// The props of Wrap config 99 | class YZWrapConfig { 100 | String? direction; 101 | String? alignment; 102 | String? spacing; 103 | String? runAlignment; 104 | String? runSpacing; 105 | String? crossAxisAlignment; 106 | String? textDirection; 107 | String? verticalDirection; 108 | List? children; 109 | 110 | YZWrapConfig( 111 | {this.direction, 112 | this.alignment, 113 | this.spacing, 114 | this.runAlignment, 115 | this.runSpacing, 116 | this.crossAxisAlignment, 117 | this.textDirection, 118 | this.verticalDirection, 119 | this.children}); 120 | 121 | YZWrapConfig.fromJson(Map? json) { 122 | json ??= {}; 123 | alignment = json['alignment']; 124 | spacing = json['spacing']; 125 | runAlignment = json['runAlignment']; 126 | runSpacing = json['runSpacing']; 127 | crossAxisAlignment = json['crossAxisAlignment']; 128 | textDirection = json['textDirection']; 129 | verticalDirection = json['verticalDirection']; 130 | if (json['children'] != null) { 131 | children = []; 132 | json['children'].forEach((v) { 133 | children!.add(v); 134 | }); 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | url: "https://pub.flutter-io.cn" 9 | source: hosted 10 | version: "2.5.0" 11 | boolean_selector: 12 | dependency: transitive 13 | description: 14 | name: boolean_selector 15 | url: "https://pub.flutter-io.cn" 16 | source: hosted 17 | version: "2.1.0" 18 | characters: 19 | dependency: transitive 20 | description: 21 | name: characters 22 | url: "https://pub.flutter-io.cn" 23 | source: hosted 24 | version: "1.1.0" 25 | charcode: 26 | dependency: transitive 27 | description: 28 | name: charcode 29 | url: "https://pub.flutter-io.cn" 30 | source: hosted 31 | version: "1.2.0" 32 | clock: 33 | dependency: transitive 34 | description: 35 | name: clock 36 | url: "https://pub.flutter-io.cn" 37 | source: hosted 38 | version: "1.1.0" 39 | collection: 40 | dependency: transitive 41 | description: 42 | name: collection 43 | url: "https://pub.flutter-io.cn" 44 | source: hosted 45 | version: "1.15.0" 46 | fake_async: 47 | dependency: transitive 48 | description: 49 | name: fake_async 50 | url: "https://pub.flutter-io.cn" 51 | source: hosted 52 | version: "1.2.0" 53 | flutter: 54 | dependency: "direct main" 55 | description: flutter 56 | source: sdk 57 | version: "0.0.0" 58 | flutter_test: 59 | dependency: "direct dev" 60 | description: flutter 61 | source: sdk 62 | version: "0.0.0" 63 | matcher: 64 | dependency: transitive 65 | description: 66 | name: matcher 67 | url: "https://pub.flutter-io.cn" 68 | source: hosted 69 | version: "0.12.10" 70 | meta: 71 | dependency: transitive 72 | description: 73 | name: meta 74 | url: "https://pub.flutter-io.cn" 75 | source: hosted 76 | version: "1.3.0" 77 | path: 78 | dependency: transitive 79 | description: 80 | name: path 81 | url: "https://pub.flutter-io.cn" 82 | source: hosted 83 | version: "1.8.0" 84 | sky_engine: 85 | dependency: transitive 86 | description: flutter 87 | source: sdk 88 | version: "0.0.99" 89 | source_span: 90 | dependency: transitive 91 | description: 92 | name: source_span 93 | url: "https://pub.flutter-io.cn" 94 | source: hosted 95 | version: "1.8.0" 96 | stack_trace: 97 | dependency: transitive 98 | description: 99 | name: stack_trace 100 | url: "https://pub.flutter-io.cn" 101 | source: hosted 102 | version: "1.10.0" 103 | stream_channel: 104 | dependency: transitive 105 | description: 106 | name: stream_channel 107 | url: "https://pub.flutter-io.cn" 108 | source: hosted 109 | version: "2.1.0" 110 | string_scanner: 111 | dependency: transitive 112 | description: 113 | name: string_scanner 114 | url: "https://pub.flutter-io.cn" 115 | source: hosted 116 | version: "1.1.0" 117 | term_glyph: 118 | dependency: transitive 119 | description: 120 | name: term_glyph 121 | url: "https://pub.flutter-io.cn" 122 | source: hosted 123 | version: "1.2.0" 124 | test_api: 125 | dependency: transitive 126 | description: 127 | name: test_api 128 | url: "https://pub.flutter-io.cn" 129 | source: hosted 130 | version: "0.2.19" 131 | typed_data: 132 | dependency: transitive 133 | description: 134 | name: typed_data 135 | url: "https://pub.flutter-io.cn" 136 | source: hosted 137 | version: "1.3.0" 138 | vector_math: 139 | dependency: transitive 140 | description: 141 | name: vector_math 142 | url: "https://pub.flutter-io.cn" 143 | source: hosted 144 | version: "2.1.0" 145 | sdks: 146 | dart: ">=2.12.0 <3.0.0" 147 | flutter: ">=1.20.0" 148 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: yz_flutter_dynamic 2 | description: A new flutter plugin project. 3 | version: 0.0.1 4 | author: 5 | homepage: 6 | 7 | environment: 8 | sdk: ">=2.12.0 <3.0.0" 9 | flutter: ">=1.20.0" 10 | 11 | dependencies: 12 | flutter: 13 | sdk: flutter 14 | 15 | dev_dependencies: 16 | flutter_test: 17 | sdk: flutter 18 | 19 | # For information on the generic Dart part of this file, see the 20 | # following page: https://dart.dev/tools/pub/pubspec 21 | 22 | # The following section is specific to Flutter. 23 | flutter: 24 | # This section identifies this Flutter project as a plugin project. 25 | # The 'pluginClass' and Android 'package' identifiers should not ordinarily 26 | # be modified. They are used by the tooling to maintain consistency when 27 | # adding or updating assets for this project. 28 | # plugin: 29 | # platforms: 30 | # android: 31 | # package: com.example.yz_flutter_dynamic 32 | # pluginClass: YzFlutterDynamicPlugin 33 | # ios: 34 | # pluginClass: YzFlutterDynamicPlugin 35 | 36 | # To add assets to your plugin package, add an assets section, like this: 37 | # assets: 38 | # - images/a_dot_burr.jpeg 39 | # - images/a_dot_ham.jpeg 40 | # 41 | # For details regarding assets in packages, see 42 | # https://flutter.dev/assets-and-images/#from-packages 43 | # 44 | # An image asset can refer to one or more resolution-specific "variants", see 45 | # https://flutter.dev/assets-and-images/#resolution-aware. 46 | 47 | # To add custom fonts to your plugin package, add a fonts section here, 48 | # in this "flutter" section. Each entry in this list should have a 49 | # "family" key with the font family name, and a "fonts" key with a 50 | # list giving the asset and other descriptors for the font. For 51 | # example: 52 | # fonts: 53 | # - family: Schyler 54 | # fonts: 55 | # - asset: fonts/Schyler-Regular.ttf 56 | # - asset: fonts/Schyler-Italic.ttf 57 | # style: italic 58 | # - family: Trajan Pro 59 | # fonts: 60 | # - asset: fonts/TrajanPro.ttf 61 | # - asset: fonts/TrajanPro_Bold.ttf 62 | # weight: 700 63 | # 64 | # For details regarding fonts in packages, see 65 | # https://flutter.dev/custom-fonts/#from-packages 66 | -------------------------------------------------------------------------------- /test/yz_flutter_dynamic_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/services.dart'; 2 | import 'package:flutter_test/flutter_test.dart'; 3 | 4 | void main() { 5 | const MethodChannel channel = MethodChannel('yz_flutter_dynamic'); 6 | 7 | TestWidgetsFlutterBinding.ensureInitialized(); 8 | 9 | setUp(() { 10 | channel.setMockMethodCallHandler((MethodCall methodCall) async { 11 | return '42'; 12 | }); 13 | }); 14 | 15 | tearDown(() { 16 | channel.setMockMethodCallHandler(null); 17 | }); 18 | 19 | test('getPlatformVersion', () async { 20 | 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /yz_flutter_dynamic.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | --------------------------------------------------------------------------------