diff --git a/.gitignore b/.gitignore
index 9213b3353..fe733f8be 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,7 +29,13 @@
.pub-cache/
.pub/
/build/
+/android/app/.cxx/
/lib/tools/
/lib/res/constant/github_client_config.dart
# Exceptions to above rules.
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
+
+/build_tools
+/libs
+/pubspec_overrides.yaml
+modules/game_system
diff --git a/README-EN.md b/README-EN.md
new file mode 100644
index 000000000..13cf46805
--- /dev/null
+++ b/README-EN.md
@@ -0,0 +1,239 @@
+
+
+ FlutterUnit🔖
+
+ ⭐️ All Platform Flutter Experience App ⭐️
+
+
+
+FlutterUnit is a cross-platform experience app, Here, you can fully explore the creativity that Flutter offers.
+
+
+
+
+
+
+
+
+
+ Download v3.0.0 :
+ [Android] •
+ [iOS] •
+ [MacOS] •
+ [Windows] •
+ [Web]
+
+
+
+
+---
+
+
+### Env and Build
+
+#### Flutter Version
+
+```
+·]>> flutter --version
+Flutter 3.35.1 • channel stable • https://github.com/flutter/flutter.git
+Framework • revision 20f8274939 (6 days ago) • 2025-08-14 10:53:09 -0700
+Engine • hash 6cd51c08a88e7bbe848a762c20ad3ecb8b063c0e (revision 1e9a811bf8) (7 days ago) • 2025-08-13 23:35:25.000Z
+Tools • Dart 3.9.0 • DevTools 2.48.0
+```
+
+#### Build Application
+
+```
+·]>> git clone https://github.com/toly1994328/FlutterUnit.git
+·]>> cd FlutterUnit
+
+Build Android:
+·]>> flutter build apk --target-platform --split-per-abi
+Build iOS:
+·]>> flutter build ios
+Build Windows:
+·]>> flutter build windows
+Build Linux:
+·]>> flutter build linux
+Build web:
+·]>> flutter build web
+```
+
+
+#### My Flutter Books
+- 🔥 [免费] [掘金小册 -《Flutter 入门教程》](https://juejin.cn/book/7212822723330834487)
+- 🔥 [掘金小册 -《Flutter 语言基础 - 梦始之地》](https://juejin.cn/book/6844733827617652750)
+- 🔥 [掘金小册 -《Flutter 绘制指南 - 妙笔生花》](https://juejin.im/book/6844733827265331214)
+- 🔥 [掘金小册 -《Flutter 手势探索 - 执掌天下》](https://juejin.cn/book/6896378716427911181)
+- 🔥 [掘金小册 -《Flutter 动画探索 - 流光幻影》](https://juejin.cn/book/6965102582473687071)
+- 🔥 [掘金小册 -《Flutter 滑动探索 - 珠联璧合》](https://juejin.cn/book/6984685333312962573)
+- 🔥 [掘金小册 -《Flutter 布局探索 - 薪火相传》](https://juejin.cn/book/7075958265250578469)
+- 🔥 [掘金小册 -《Flutter 渲染机制 - 聚沙成塔》](https://juejin.cn/book/6965102582473687071)
+
+---
+
+- [Flutter环境配置](https://github.com/toly1994328/FlutterUnit/issues/22)
+- [Flutter实用插件集录 ](https://github.com/toly1994328/FlutterUnit/issues/41)
+- [Flutter要点集录 ](https://github.com/toly1994328/FlutterUnit/labels/point)
+
+
+---
+
+
+#### MacOS 桌面版本组件界面
+
+
+
+#### Windows 桌面版本组件界面
+
+
+
+
+> 开源不易,请我喝咖啡 ~
+
+
+
+
+
+#### Star History
+
+[](https://star-history.com/#toly1994328/FlutterUnit&Date)
+
+### 一、组件的展示页面
+
+#### 1. `300+组件收录`
+
+> Flutter源码中的可用的组件一共350个左右,纷繁复杂,也没有明确的分类标准
+FlutterUnit 对`大大小小,常用不常用`的组件能收的尽量收录。并`根据个人感觉进行评星 `
+`目前收录组件306个`,每个都有至少一个演示展现和代码展示。
+
+| . | . | . |
+|------|------------|------------|
+| | |  |
+
+---
+
+#### 2. 组件详情页
+
+> `213个组件`全部都有详情页。对于重要的组件会详细展现
+一般都会有某个演示对应的组件和属性,尽量做到细致,如果有需要补充,欢迎联系我。
+`最重要的是: 所有的演示展现都是Flutter的组件形成的,而非图片,这就意味着可操作性更高。`
+
+| . | . | . |
+|------|------------|------------|
+| | |  |
+|  |  ||
+
+---
+
+#### 3. 组件的可操作性
+
+> 对一些操作交互的组件或有可操作性的某些组件,`提供操作演示`
+
+| . | . | . |
+|------|------------|------------|
+| | | |
+|  |  ||
+
+---
+
+#### 4. 相关组件的关联切换
+> `相关组件通过link to 可以进行切换, 满足你的探索欲。`
+如果有的关联未加入,欢迎联系我,对我来说,加个数字就行了。
+
+| . | . | . |
+|------|------------|------------|
+||| |
+
+
+---
+
+#### 5. 代码的查看和分享
+> 激动人心的是,你可以通过右侧的图标`展开/隐藏 实现下面效果的代码`
+并且`支持分享`,如果你想亲自体验,so,easy ! 而且`代码高亮样式可以自定义`。
+
+
+| . | . | . |
+|------|------------|------------|
+| | | |
+
+---
+
+
+### 二、全局配置
+
+#### 1. 颜色主题
+> 只提供八种颜色,可在`右滑菜单页`的`我的主题`配置,`可以拓展`
+
+| . | . | . |
+|------|------------|------------|
+| |  |  |
+
+---
+
+
+#### 2.字体配置
+
+> 支持全局字体设置,`可以拓展`
+
+| . | . | . |
+|------|------------|------------|
+| |  | |
+---
+
+
+#### 3.item样式设置
+
+> 支持item样式设置,`可以拓展,支持征集`,详见`Flutter Unit 1.0 征集方案`
+
+| . | . | . |
+|------|------------|------------|
+|| | |
+---
+
+#### 4.代码面板风格设置
+
+> 支持代码风格设置,`可以拓展,支持征集`,详见`Flutter Unit 1.0 征集方案`
+
+| . | . |
+|------|------------|
+|| |
+||
+
+---
+
+
+
+### 三、搜索与收藏功能
+
+
+#### 1.搜索功能
+
+> 由于Flutter中Widget比较杂乱,不太好分类,所以搜索是非常重要的
+另外可以根据星级进行过滤,支持多选。目前正在考虑根据功能分类,之后会有所完善。
+
+
+| . | . | . |
+|------|------------|------------|
+| | |  |
+
+---
+
+#### 2.收藏功能
+
+| 添加收藏集 | 修改收藏集 | 删除收藏集 |
+|------|------------|------------|
+|  |  |  |
+
+| 长按右菜单滑页 | 长按左菜单滑页 | 详情内长按展示收藏菜单 |
+|------|------------|------------|
+|  | |  |
+
+| 删除与数据同步 | 组件加入收藏集 | 收藏集支持多选 |
+|------|------------|------------|
+|  |  |  |
+
+> `FlutterUnit 2.0 `目前基本就是这么多功能,可以在Github中下载打包后的apk玩玩
+希望能对你的Flutter学习有所帮助。
+
+---
diff --git a/README.md b/README.md
index 5d6a56eb5..0881234c8 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,62 @@
+
+
+ FlutterUnit
+
+ ⭐️ 全平台 Flutter 探索应用 ⭐️
+
+
+
+FlutterUnit 是一个全平台体验应用,你可以在这里尽情体验 Flutter 带来的创造力。
+
+
+
+
+
+
+
+
+
+ 下载 App:
+ [Android] •
+ [iOS] •
+ [MacOS] •
+ [Windows] •
+ [Web]
+
+
+
-### FlutterUnit 全平台下载体验:
+---
+
+### 环境与构建
+
+#### Flutter 版本
-| 平台类型 | 下载地址 | 项目分支地址 | 相关文章 |
-|------|------------|------|------------|
-| Android版 | [FlutterUnit.apk](https://github.com/toly1994328/FlutterUnit/releases/download/v2.9.3/FlutterUnit.apk) |[flutter_unit](https://github.com/toly1994328/FlutterUnit)| [《FlutterUnit食用指南》](https://juejin.im/post/6844904147045597191)|
-| iOS版 |[FlutterUnit in AppStore](https://apps.apple.com/cn/app/flutter-unit/id6450545123) |[flutter_unit](https://github.com/toly1994328/FlutterUnit)| [《FlutterUnit 食用指南》](https://juejin.im/post/6844904147045597191)|
-| MacOS版 | [FlutterUnitMac.zip](https://github.com/toly1994328/FlutterUnit/releases/download/v2.9.3/FlutterUnitMac.zip) |[flutter_unit](https://github.com/toly1994328/FlutterUnit/tree/flutter_unit)| [《mac版闪亮登场》](https://juejin.im/post/6844904147817332743)|
-| Windows版 |[FlutterUnitWin.zip](https://github.com/toly1994328/FlutterUnit/releases/download/v2.9.3/FlutterUnitWin.zip) | [flutter_unit](https://github.com/toly1994328/FlutterUnit/tree/flutter_unit) | [《win版闪亮登场》](https://juejin.im/post/6847902222626488327)|
-| Web版 | http://toly1994328.gitee.io/flutter_web | [ flutter_unit_web ](https://github.com/toly1994328/FlutterUnit/tree/flutter_unit_web) | [《web版闪亮登场》](https://juejin.im/post/6859888713980182541)|
+```
+·]>> flutter --version
+Flutter 3.35.1 • channel stable • https://github.com/flutter/flutter.git
+Framework • revision 20f8274939 (6 days ago) • 2025-08-14 10:53:09 -0700
+Engine • hash 6cd51c08a88e7bbe848a762c20ad3ecb8b063c0e (revision 1e9a811bf8) (7 days ago) • 2025-08-13 23:35:25.000Z
+Tools • Dart 3.9.0 • DevTools 2.48.0
+```
+#### 构建应用
+
+```
+·]>> git clone https://github.com/toly1994328/FlutterUnit.git
+·]>> cd FlutterUnit
+
+Build Android:
+·]>> flutter build apk --target-platform --split-per-abi
+Build iOS:
+·]>> flutter build ios
+Build Windows:
+·]>> flutter build windows
+Build Linux:
+·]>> flutter build linux
+Build web:
+·]>> flutter build web
+```
#### Flutter Unit 周边
- 🔥 [免费] [掘金小册 -《Flutter 入门教程》](https://juejin.cn/book/7212822723330834487)
@@ -26,27 +74,6 @@
- [Flutter实用插件集录 ](https://github.com/toly1994328/FlutterUnit/issues/41)
- [Flutter要点集录 ](https://github.com/toly1994328/FlutterUnit/labels/point)
-
----
-
-#### 当前Flutter 版本
-
-```
-Flutter 3.16.3 • channel stable • https://github.com/flutter/flutter.git
-Framework • revision b0366e0a3f (2 weeks ago) • 2023-12-05 19:46:39 -0800
-Engine • revision 54a7145303
-Tools • Dart 3.2.3 • DevTools 2.28.4
-```
-
-#### 构建命令,产出应用
-
-> Android 分架构打包: flutter build apk --target-platform android-arm64 --split-per-abi
-> iOS 打包应用: flutter build ios
-> Windows 打包应用: flutter build windows
-> Macos 打包应用: flutter build macos
-> Linux 打包应用: flutter build linux
-> web 打包应用: flutter build web
-
---
#### MacOS 桌面版本组件界面
@@ -60,7 +87,7 @@ Tools • Dart 3.2.3 • DevTools 2.28.4
> 开源不易,请我喝咖啡 ~
-
+
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 2fdeaeb06..d54e87f36 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -10,21 +10,13 @@
include: package:flutter_lints/flutter.yaml
linter:
- # The lint rules applied to this project can be customized in the
- # section below to disable rules from the `package:flutter_lints/flutter.yaml`
- # included above or to enable additional rules. A list of all available lints
- # and their documentation is published at
- # https://dart-lang.github.io/linter/lints/index.html.
- #
- # Instead of disabling a lint rule for the entire project in the
- # section below, it can also be suppressed for a single line of code
- # or a specific dart file by using the `// ignore: name_of_lint` and
- # `// ignore_for_file: name_of_lint` syntax on the line or in the file
- # producing the lint.
rules:
avoid_print: false # Uncomment to disable the `avoid_print` rule
file_names: false
- # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
-# Additional information about this file can be found at
-# https://dart.dev/guides/language/analysis-options
+analyzer:
+# exclude:
+# - modules/widget_system/widgets/**
+
+
+
diff --git a/android/app/build.gradle b/android/app/build.gradle
deleted file mode 100644
index a3efbb853..000000000
--- a/android/app/build.gradle
+++ /dev/null
@@ -1,74 +0,0 @@
-def localProperties = new Properties()
-def localPropertiesFile = rootProject.file('local.properties')
-if (localPropertiesFile.exists()) {
- localPropertiesFile.withReader('UTF-8') { reader ->
- localProperties.load(reader)
- }
-}
-
-def flutterRoot = localProperties.getProperty('flutter.sdk')
-if (flutterRoot == null) {
- throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
-}
-
-def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
-if (flutterVersionCode == null) {
- flutterVersionCode = '1'
-}
-
-def flutterVersionName = localProperties.getProperty('flutter.versionName')
-if (flutterVersionName == null) {
- flutterVersionName = '1.0'
-}
-
-apply plugin: 'com.android.application'
-apply plugin: 'kotlin-android'
-apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
-
-android {
- compileSdkVersion 33
-
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
- }
-
- kotlinOptions {
- jvmTarget = '1.8'
- }
-
- sourceSets {
- main.java.srcDirs += 'src/main/kotlin'
- }
-
- defaultConfig {
- // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
- applicationId "com.toly1994.flutter_unit"
- minSdkVersion 19
- targetSdkVersion 30
- versionCode flutterVersionCode.toInteger()
- versionName flutterVersionName
- multiDexEnabled true
- archivesBaseName = "FlutterUnit.apk"
- ndk {
-// abiFilters 'arm64-v8a'
-// abiFilters 'armeabi', 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a'
- }
- }
-
- buildTypes {
- release {
- // TODO: Add your own signing config for the release build.
- // Signing with the debug keys for now, so `flutter run --release` works.
- signingConfig signingConfigs.debug
- }
- }
-}
-
-flutter {
- source '../..'
-}
-
-dependencies {
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
-}
diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts
new file mode 100644
index 000000000..d73f8c2d9
--- /dev/null
+++ b/android/app/build.gradle.kts
@@ -0,0 +1,53 @@
+plugins {
+ id("com.android.application")
+ id("kotlin-android")
+ // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
+ id("dev.flutter.flutter-gradle-plugin")
+}
+
+android {
+ namespace = "com.toly1994.flutter_unit"
+ compileSdk = flutter.compileSdkVersion
+ ndkVersion = flutter.ndkVersion
+
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
+ }
+
+ kotlinOptions {
+ jvmTarget = JavaVersion.VERSION_11.toString()
+ }
+
+ defaultConfig {
+ // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
+ applicationId = "com.toly1994.flutter_unit"
+ // You can update the following values to match your application needs.
+ // For more information, see: https://flutter.dev/to/review-gradle-config.
+ minSdk = flutter.minSdkVersion
+ targetSdk = flutter.targetSdkVersion
+ versionCode = flutter.versionCode
+ versionName = flutter.versionName
+ }
+
+ buildTypes {
+ getByName("release") {
+ // TODO: Add your own signing config for the release build.
+ // Signing with the debug keys for now, so `flutter run --release` works.
+ signingConfig = signingConfigs.getByName("debug")
+ isShrinkResources = true // 移除未使用的资源
+ isMinifyEnabled = true // 启用 R8 代码压缩
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ ndk {
+ debugSymbolLevel = "none"
+ }
+ }
+ }
+}
+
+flutter {
+ source = "../.."
+}
diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro
new file mode 100644
index 000000000..e9ffa01ad
--- /dev/null
+++ b/android/app/proguard-rules.pro
@@ -0,0 +1,2 @@
+-dontwarn javax.annotation.**
+-keep class javax.annotation.** { *; }
\ No newline at end of file
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 932ba74d6..678734418 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -1,6 +1,8 @@
-
+
+
+
+
@@ -28,6 +30,7 @@
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
+ android:exported="true"
android:windowSoftInputMode="adjustResize">
上\nclass Bottom2TopRouter extends PageRouteBuilder {\n final Widget child;\n final int duration;\n final Curve curve;\n\n Bottom2TopRouter(\n {this.child, this.duration = 500, this.curve = Curves.fastOutSlowIn})\n : super(\n transitionDuration: Duration(milliseconds: duration),\n pageBuilder: (ctx, a1, a2) {\n return child;\n },\n transitionsBuilder: (\n ctx,\n a1,\n a2,\n Widget child,\n ) => SlideTransition(\n position: Tween(\n begin: Offset(0.0, 1.0),\n end: Offset(0.0, 0.0),\n ).animate(CurvedAnimation(parent: a1, curve: curve)),\n child: child));\n}\n"},{"id":null,"widgetId":174,"name":"PopupMenuDivider基本使用","priority":1,"subtitle":" \n【height】 : 高度 【double】","code":"import 'package:flutter/material.dart';\nimport '../../../dialogs/dialog_about.dart';\nclass CustomPopupMenuDivider extends StatelessWidget {\n final map = {\n \"关于\": Icons.info_outline,\n \"帮助\": Icons.help_outline,\n \"问题反馈\": Icons.add_comment,\n };\n\n @override\n Widget build(BuildContext context) {\n return Container(\n child: Column(\n children: [\n _buildPopupMenuButton(context),\n PopupMenuDivider(),\n ],\n ),\n );\n }\n\n PopupMenuButton _buildPopupMenuButton(BuildContext context) {\n return PopupMenuButton(\n itemBuilder: (context) => [\n ...buildItems().sublist(0, 2),\n PopupMenuDivider(),\n ...buildItems().sublist(2, 3)\n ],\n offset: Offset(0, 50),\n color: Color(0xffF4FFFA),\n elevation: 1,\n shape: RoundedRectangleBorder(\n borderRadius: BorderRadius.only(\n topLeft: Radius.circular(20),\n bottomRight: Radius.circular(20),\n topRight: Radius.circular(5),\n bottomLeft: Radius.circular(5),\n )),\n onSelected: (e) {\n print(e);\n if (e == '关于') {\n DialogAbout.show(context);\n }\n },\n onCanceled: () => print('onCanceled'),\n );\n }\n\n List> buildItems() {\n return map.keys\n .toList()\n .map((e) => PopupMenuItem(\n value: e,\n child: Wrap(\n spacing: 10,\n children: [\n Icon(\n map[e],\n color: Colors.blue,\n ),\n Text(e),\n ],\n )))\n .toList();\n }\n}\n"},{"id":null,"widgetId":195,"name":"CupertinoScrollbar基本使用","priority":1,"subtitle":" \n【child】 : 子组件 【Widget】\n【controller】 : 控制器 【ScrollController】","code":"import 'package:flutter/cupertino.dart';\nimport 'package:flutter/material.dart';\nclass CustomCupertinoScrollbar extends StatelessWidget {\n final data = [\n Colors.purple[50],\n Colors.purple[100],\n Colors.purple[200],\n Colors.purple[300],\n Colors.purple[400],\n Colors.purple[500],\n Colors.purple[600],\n Colors.purple[700],\n Colors.purple[800],\n Colors.purple[900],\n ];\n\n @override\n Widget build(BuildContext context) {\n return Container(\n height: 200,\n child: CupertinoScrollbar(\n child: ListView(\n padding: EdgeInsets.symmetric(horizontal: 5),\n children: data\n .map((color) => Container(\n alignment: Alignment.center,\n width: 100,\n height: 50,\n color: color,\n child: Text(\n colorString(color),\n style: TextStyle(color: Colors.white, shadows: [\n Shadow(\n color: Colors.black,\n offset: Offset(.5, .5),\n blurRadius: 2)\n ]),\n ),\n ))\n .toList(),\n ),\n ),\n );\n }\n\n String colorString(Color color) =>\n \"#${color.value.toRadixString(16).padLeft(8, '0').toUpperCase()}\";\n}"},{"id":null,"widgetId":172,"name":"FutureBuilder基本使用","priority":1,"subtitle":" \n【builder】 : 子组件 【AsyncWidgetBuilder】\n【initialData】 : 初始数据 【T】\n【future】 : 异步任务 【Future】","code":"import 'package:flutter/material.dart';\nclass CustomFutureBuilder extends StatefulWidget {\n @override\n _CustomFutureBuilderState createState() => _CustomFutureBuilderState();\n}\n\nclass _CustomFutureBuilderState extends State {\n Future _future;\n\n @override\n void initState() {\n _future = loadData();\n super.initState();\n }\n\n @override\n Widget build(BuildContext context) {\n return Container(\n child: FutureBuilder(\n initialData: 'Load',\n future: _future,\n builder: (ctx, snap) {\n if (snap.connectionState == ConnectionState.done) {\n return Text(snap.data);\n }\n if (snap.connectionState == ConnectionState.waiting) {\n return CircularProgressIndicator();\n }\n if (snap.hasError) {\n return Text('Error');\n }\n return Container();\n }),\n );\n }\n\n Future loadData() async {\n await Future.delayed(Duration(seconds: 2));\n return 'LoadeSuccess';\n }\n}\n"},{"id":null,"widgetId":182,"name":"Overlay基本使用","priority":1,"subtitle":" \n Overlay.of(context).insert插入全局组件","code":"import 'package:flutter/material.dart';\nclass CustomOverlay extends StatelessWidget {\n @override\n Widget build(BuildContext context) {\n return Wrap(\n children: [\n Container(\n height: 50,\n child: RawMaterialButton(\n elevation: 2,\n shape: CircleBorder(\n side: BorderSide(width: 2.0, color: Color(0xFFFFDFDFDF)),\n ),\n fillColor: Colors.blue,\n splashColor: Colors.orange,\n textStyle: TextStyle(color: Colors.white),\n child: Icon(Icons.add),\n onPressed: ()=>showFloating(context),\n ),\n ),\n Container(\n height: 50,\n child: RawMaterialButton(\n elevation: 2,\n shape: CircleBorder(\n side: BorderSide(width: 2.0, color: Color(0xFFFFDFDFDF)),\n ),\n fillColor: Colors.red,\n splashColor: Colors.orange,\n textStyle: TextStyle(color: Colors.white),\n child: Icon(Icons.remove),\n onPressed: hideFloating,\n ),\n ),\n ],\n );\n }\n}\n"},{"id":null,"widgetId":139,"name":"CupertinoPicker基本使用","priority":1,"subtitle":" \n【children】 : 子组件列表 【List】\n【offAxisFraction】 : 轴偏移率 【double】\n【squeeze】 : 挤压率 【double】\n【diameterRatio】 : 高与圆柱直径比率 【double】\n【itemExtent】 : 间距 【double】\n【backgroundColor】 : 背景色 【Color】\n【onSelectedItemChanged】 : 选中事件 【Function(int)】","code":"import 'package:flutter/cupertino.dart';\nclass CustomCupertinoPicker extends StatelessWidget {\n final names = [\n 'Java',\n 'Kotlin',\n 'Dart',\n 'Swift',\n 'C++',\n 'Python',\n \"JavaScript\",\n \"PHP\",\n \"Go\",\n \"Object-c\"\n ];\n\n @override\n Widget build(BuildContext context) {\n return Container(\n height: 150,\n child: CupertinoPicker(\n backgroundColor: CupertinoColors.systemGrey.withAlpha(33),\n diameterRatio: 1,\n offAxisFraction: 0.4,\n squeeze: 1.5,\n itemExtent: 40,\n onSelectedItemChanged: (position) {\n print('当前条目 ${names[position]}');\n },\n children: names.map((e) => Center(child: Text(e))).toList()),\n );\n }\n}\n"},{"id":null,"widgetId":118,"name":"AnimatedOpacity基本使用","priority":1,"subtitle":" \n【child】 : 孩子组件 【Widget】\n【duration】 : 动画时长 【Duration】\n【onEnd】 : 动画结束回调 【Function()】\n【curve】 : 动画曲线 【Duration】\n【opacity】 : 透明度 【double】","code":"import 'package:flutter/material.dart';\nclass CustomAnimatedOpacity extends StatefulWidget {\n @override\n _CustomAnimatedOpacityState createState() => _CustomAnimatedOpacityState();\n}\n\nclass _CustomAnimatedOpacityState extends State {\n double _opacity = 1.0;\n\n @override\n Widget build(BuildContext context) {\n return Column(\n children: [\n Switch(\n value: _opacity == 0,\n onChanged: (v) {\n setState(() {\n _opacity = v ? 0 : 1.0;\n });\n }),\n Container(\n color: Colors.grey.withAlpha(22),\n width: 200,\n height: 100,\n child: AnimatedOpacity(\n duration: Duration(seconds: 1),\n curve: Curves.fastOutSlowIn,\n opacity: _opacity,\n onEnd: () => print('End'),\n child: Icon(Icons.android, color: Colors.green, size: 60),\n ),\n ),\n ],\n );\n }\n}\n"},{"id":null,"widgetId":55,"name":"DropdownButton的样式指定","priority":2,"subtitle":" \n【isDense】 : 是否紧排 【bool】\n【iconSize】 : 图标大小 【double】\n【hint】 : 提示组件 【Widget】\n【iconEnabledColor】 : 图标颜色 【Color】","code":"import 'package:flutter/material.dart';\nclass StyleDropDownButton extends StatefulWidget {\n @override\n _StyleDropDownButtonState createState() => _StyleDropDownButtonState();\n}\n\nclass _StyleDropDownButtonState extends State {\n Color _color = Colors.red ;\n final _colors = [Colors.red, Colors.yellow, Colors.blue, Colors.green];\n final _info = [\"红色\", \"黄色\", \"蓝色\", \"绿色\"];\n\n @override\n Widget build(BuildContext context) {\n return Wrap(\n crossAxisAlignment: WrapCrossAlignment.center,\n children: [\n Container(\n margin: EdgeInsets.symmetric(horizontal: 20),\n width: 50,\n height: 50,\n color: _color??Colors.transparent,\n ),\n DropdownButton(\n hint: Text('请选择'),\n isDense: true,\n iconSize:20,\n iconEnabledColor:_color??Colors.orange,\n value: _color,\n items: _buildItems(),\n onChanged: (v) => setState(() => _color = v)),\n ],\n );\n }\n\n List> _buildItems() => _colors\n .map((e) => DropdownMenuItem(\n value: e,\n child: Text(\n _info[_colors.indexOf(e)],\n style: TextStyle(color: e),\n )))\n .toList();\n}\n"},{"id":null,"widgetId":55,"name":"DropdownButton基本用法","priority":1,"subtitle":" \n【value】 : 当前值 【T】\n【items】 : 下拉选框 【List>】\n【icon】 : 图标 【Widget】\n【elevation】 : 影深 【double】\n【onChanged】 : 选择条目事件 【Function(T)】\n【backgroundColor】 : 背景色 【Color】","code":"import 'package:flutter/material.dart';\nclass CustomDropDownButton extends StatefulWidget {\n @override\n _CustomDropDownButtonState createState() => _CustomDropDownButtonState();\n}\n\nclass _CustomDropDownButtonState extends State {\n Color _color = Colors.red;\n final _colors = [Colors.red, Colors.yellow, Colors.blue, Colors.green];\n final _info = [\"红色\", \"黄色\", \"蓝色\", \"绿色\"];\n\n @override\n Widget build(BuildContext context) {\n return Wrap(\n children: [\n Container(\n margin: EdgeInsets.symmetric(horizontal: 20),\n width: 50,\n height: 50,\n color: _color,\n ),\n DropdownButton(\n value: _color,\n elevation: 1,\n icon: Icon(\n Icons.expand_more,\n size: 20,\n color: _color,\n ),\n items: _buildItems(),\n onChanged: (v) => setState(() => _color = v)),\n ],\n );\n }\n\n List> _buildItems() => _colors\n .map((e) => DropdownMenuItem(\n value: e,\n child: Text(\n _info[_colors.indexOf(e)],\n style: TextStyle(color: e),\n )))\n .toList();\n}"},{"id":null,"widgetId":56,"name":"PopupMenuButton基本使用","priority":1,"subtitle":" \n【itemBuilder】 : 构造器 【PopupMenuItemBuilder】\n【offset】 : 偏移 【Offset】\n【color】 : 背景颜色 【Color】\n【shape】 : 形状 【ShapeBorder】\n【elevation】 : 影深 【double】\n【onCanceled】 : 取消事件 【Function()】\n【onSelected】 : 选择事件 【Function(T)】","code":"import 'package:flutter/material.dart';\nimport '../../../dialogs/dialog_about.dart';\nclass CustomPopupMenuButton extends StatefulWidget {\n @override\n _CustomPopupMenuButtonState createState() => _CustomPopupMenuButtonState();\n}\n\nclass _CustomPopupMenuButtonState extends State {\n final map = {\n \"关于\": Icons.info_outline,\n \"帮助\": Icons.help_outline,\n \"问题反馈\": Icons.add_comment,\n };\n\n @override\n Widget build(BuildContext context) {\n return PopupMenuButton(\n itemBuilder: (context) => buildItems(),\n offset: Offset(0, 50),\n color: Color(0xffF4FFFA),\n elevation: 1,\n shape: RoundedRectangleBorder(\n borderRadius: BorderRadius.only(\n topLeft: Radius.circular(20),\n bottomRight: Radius.circular(20),\n topRight: Radius.circular(5),\n bottomLeft: Radius.circular(5),\n )),\n onSelected: (e) {\n print(e);\n if (e == '关于') {\n DialogAbout.show(context);\n }\n },\n onCanceled: () => print('onCanceled'),\n );\n }\n\n List> buildItems() {\n return map.keys\n .toList()\n .map((e) => PopupMenuItem(\n value: e,\n child: Wrap(\n spacing: 10,\n children: [\n Icon(\n map[e],\n color: Colors.blue,\n ),\n Text(e),\n ],\n )))\n .toList();\n }\n}\n"},{"id":null,"widgetId":160,"name":"Material的shape属性","priority":2,"subtitle":" \n【shape】 : 形状 【ShapeBorder】,","code":"import 'package:flutter/material.dart';\nclass ShapeMaterial extends StatelessWidget {\n\n final shapeMap = {\n 'BorderDirectional': BorderDirectional(\n top: BorderSide(\n color: Colors.white,\n ),\n start: BorderSide(color: Colors.black, width: 15),\n bottom: BorderSide(\n color: Colors.white,\n )),\n 'Border': Border(\n top: BorderSide(width: 5.0, color: Color(0xFFFFDFDFDF)),\n left: BorderSide(width: 5.0, color: Color(0xFFFFDFDFDF)),\n right: BorderSide(width: 5.0, color: Color(0xFFFF7F7F7F)),\n bottom: BorderSide(width: 5.0, color: Color(0xFFFF7F7F7F)),\n ),\n 'Circle': CircleBorder(\n side: BorderSide(width: 2.0, color: Color(0xFFFFDFDFDF)),\n ),\n 'RoundedRectangleBorder': RoundedRectangleBorder(\n side: BorderSide(width: 1.0, color: Colors.black),\n borderRadius: BorderRadius.all(Radius.circular(15))),\n 'ContinuousRectangleBorder': ContinuousRectangleBorder(\n side: BorderSide.none,\n borderRadius: BorderRadius.circular(40.0),\n )\n };\n\n @override\n Widget build(BuildContext context) {\n return Wrap(\n spacing: 10,\n runSpacing: 10,\n children: shapeMap.keys.map((e) => _buildMaterial(e)).toList());\n }\n\n Material _buildMaterial(String type) => Material(\n shadowColor: Colors.blue,\n shape: shapeMap[type],\n color: Colors.orange,\n elevation: 3,\n textStyle: TextStyle(color: Colors.white),\n child: Container(\n alignment: Alignment.center,\n width: 300,\n height: 60,\n child: Text(\n type,\n ),\n ),\n );\n}\n"},{"id":null,"widgetId":160,"name":"Material基本使用","priority":1,"subtitle":" \n【child】 : 子组件 【Widget】\n【type】 : 类型 【MaterialType】\n【elevation】 : 影深 【double】\n【shadowColor】 : 阴影颜色 【Color】\n【color】 : 颜色 【Color】","code":"import 'package:flutter/material.dart';\nclass CustomMaterial extends StatelessWidget {\n @override\n Widget build(BuildContext context) {\n return Wrap(\n spacing: 10,\n runSpacing: 10,\n children: MaterialType.values.map((e) => _buildMaterial(e)).toList());\n }\n\n Material _buildMaterial(MaterialType type) => Material(\n shadowColor: Colors.blue,\n type: type,\n color: Colors.orange,\n elevation: 3,\n child: Container(\n alignment: Alignment.center,\n width: 100,\n height: 60,\n child: Text(\n type.toString().split('.')[1],\n style: TextStyle(color: Colors.black),\n ),\n ),\n );\n}\n"},{"id":null,"widgetId":194,"name":"Scrollbar基本使用","priority":1,"subtitle":" \n【child】 : 子组件 【Widget】\n【controller】 : 控制器 【ScrollController】","code":"import 'package:flutter/material.dart';\nclass CustomScrollbar extends StatelessWidget {\n final data = [\n Colors.purple[50],\n Colors.purple[100],\n Colors.purple[200],\n Colors.purple[300],\n Colors.purple[400],\n Colors.purple[500],\n Colors.purple[600],\n Colors.purple[700],\n Colors.purple[800],\n Colors.purple[900],\n ];\n\n @override\n Widget build(BuildContext context) {\n return Container(\n height: 200,\n child: Scrollbar(\n child: ListView(\n padding: EdgeInsets.symmetric(horizontal: 5),\n children: data\n .map((color) => Container(\n alignment: Alignment.center,\n width: 100,\n height: 50,\n color: color,\n child: Text(\n colorString(color),\n style: TextStyle(color: Colors.white, shadows: [\n Shadow(\n color: Colors.black,\n offset: Offset(.5, .5),\n blurRadius: 2)\n ]),\n ),\n ))\n .toList(),\n ),\n ),\n );\n }\n\n String colorString(Color color) =>\n \"#${color.value.toRadixString(16).padLeft(8, '0').toUpperCase()}\";\n}"},{"id":null,"widgetId":170,"name":"WillPopScope使用","priority":1,"subtitle":" \n【child】 : 子组件 【Widget】\n【onWillPop】 : 返回回调 【WillPopCallback】","code":"import 'package:flutter/material.dart';\nclass CustomWillPopScope extends StatelessWidget {\n @override\n Widget build(BuildContext context) {\n return Container(\n child: WillPopScope(child: (BackButton()),\n onWillPop: ()=>_willPop(context)),\n );\n }\n\n Future _willPop(context) async{\n return await showDialog(\n context: context,\n builder: (context) => AlertDialog(\n shape: RoundedRectangleBorder(\n borderRadius: BorderRadius.all(Radius.circular(10))),\n title: Text('提示'),\n content: Text('你确定要离开此页吗?'),\n actions: [\n FlatButton(\n onPressed: () => Navigator.of(context).pop(true),\n child: Text('确定'),\n ),\n FlatButton(\n onPressed: () => Navigator.of(context).pop(false),\n child: Text('取消'),\n ),\n\n ],\n ),\n ) ?? false;\n\n }\n}\n"},{"id":null,"widgetId":151,"name":"TableRowInkWell基本事件","priority":1,"subtitle":" \n【child】 : 子组件 【Widget】\n【onTap】 : 点击事件 【Function()】\n【onDoubleTap】 : 双击事件 【Function()】\n【onLongPress】 : 长按事件 【Function()】\n【onHighlightChanged】 : 高亮变化回调 【Function(bool)】","code":"import 'package:flutter/material.dart';\nclass CustomTableRowInkWell extends StatelessWidget {\n @override\n Widget build(BuildContext context) {\n var title = _ItemBean(\"单位称\", \"量纲\", \"单位\", \"单位名称\", \"单位符号\");\n var m = _ItemBean(\"长度\", \"L\", \"1m\", \"米\", \"m\");\n var kg = _ItemBean(\"质量\", \"M\", \"1Kg\", \"千克\", \"Kg\");\n var s = _ItemBean(\"时间\", \"T\", \"1s\", \"秒\", \"s\");\n var a = _ItemBean(\"安培\", \"Ι\", \"1A\", \"安培\", \"A\");\n var k = _ItemBean(\"热力学温度\", \"θ\", \"1K\", \"开尔文\", \"K\");\n var mol = _ItemBean(\"物质的量\", \"N\", \"1mol\", \"摩尔\", \"mol\");\n var cd = _ItemBean(\"发光强度\", \"J\", \"1cd\", \"坎德拉\", \"cd\");\n\n var data = <_ItemBean>[title, m, kg, s, a, k, mol, cd];\n\n return SingleChildScrollView(\n scrollDirection: Axis.horizontal,\n child: Table(\n columnWidths: const {\n 0: FixedColumnWidth(80.0),\n 1: FixedColumnWidth(80.0),\n 2: FixedColumnWidth(80.0),\n 3: FixedColumnWidth(80.0),\n 4: FixedColumnWidth(80.0),\n },\n defaultVerticalAlignment: TableCellVerticalAlignment.middle,\n border: TableBorder.all(\n color: Colors.orangeAccent, width: 1.0, style: BorderStyle.solid),\n children: data\n .map((item) => TableRow(children: [\n TableRowInkWell(\n onTap: () => print('onTap'),\n onDoubleTap: () => print('onDoubleTap'),\n onLongPress: () => print('onLongPress'),\n onHighlightChanged: (v) => print('onHighlightChanged:$v'),\n child: Center(\n child: Text(\n item.name,\n style: TextStyle(color: Colors.blue),\n )),\n ),\n Padding(\n padding: const EdgeInsets.all(8.0),\n child: Center(child: Text(item.symbol)),\n ),\n Padding(\n padding: const EdgeInsets.all(8.0),\n child: Center(child: Text(item.unitSymbol)),\n ),\n Padding(\n padding: const EdgeInsets.all(8.0),\n child: Center(child: Text(item.unitName)),\n ),\n Padding(\n padding: const EdgeInsets.all(8.0),\n child: Center(child: Text(item.unit)),\n ),\n ]))\n .toList(),\n ),\n );\n }\n}\n\nclass _ItemBean {\n String name;\n String symbol;\n String unit;\n String unitName;\n String unitSymbol;\n\n _ItemBean(this.name, this.symbol, this.unit, this.unitName, this.unitSymbol);\n}\n\n"},{"id":null,"widgetId":135,"name":"MonthPicker基本使用","priority":1,"subtitle":" \n【selectedDate】 : 选中日期 【DateTime】\n【firstDate】 : 最前日期限制 【DateTime】\n【lastDate】 : 最后日期限制 【DateTime】\n【onChanged】 : 点击回调 【Function(DateTime)】","code":"import 'package:flutter/material.dart';\nclass CustomMonthPicker extends StatefulWidget {\n @override\n _CustomMonthPickerState createState() => _CustomMonthPickerState();\n}\n\nclass _CustomMonthPickerState extends State {\n DateTime _date = DateTime.now();\n\n @override\n Widget build(BuildContext context) {\n return Container(\n height: 350,\n child: MonthPicker(\n selectedDate: _date,\n onChanged: (date) => setState(() => _date = date),\n firstDate: DateTime(2018),\n lastDate: DateTime(2030),\n ),\n );\n }\n}\n"},{"id":null,"widgetId":143,"name":"CupertinoContextMenu基本使用","priority":1,"subtitle":" \n【child】 : 子组件 【Widget】\n【actions】 : 行为组件集 【List】\n【previewBuilder】 : 动画构造器 【ContextMenuPreviewBuilder】","code":"import 'package:flutter/cupertino.dart';\nimport 'package:flutter/material.dart';\nclass CustomCupertinoContextMenu extends StatelessWidget {\n @override\n Widget build(BuildContext context) {\n return Container(\n child: _buildCupertinoContextMenu(context),\n );\n }\n\n final info= ['保存图片','立刻呼叫','添加到收藏夹'];\n\n Widget _buildCupertinoContextMenu(context) => Container(\n decoration: BoxDecoration(\n image: DecorationImage(\n image: AssetImage('assets/images/sabar_bar.jpg'),\n fit: BoxFit.cover),\n borderRadius: BorderRadius.all(Radius.circular(50))),\n width: 100,\n height: 100,\n child: CupertinoContextMenu(\n child: Container(\n decoration: BoxDecoration(\n image: DecorationImage(\n image: AssetImage('assets/images/sabar_bar.jpg'),\n fit: BoxFit.cover),\n borderRadius: BorderRadius.all(Radius.circular(50))),\n ),\n actions: info.map((e)=>CupertinoContextMenuAction(\n child: Center(child: Text(e)),\n onPressed: () => Navigator.pop(context),\n )).toList())\n );\n}\n"}]
\ No newline at end of file
diff --git a/assets/data/web/widget.json b/assets/data/web/widget.json
new file mode 100644
index 000000000..8dd52f79c
--- /dev/null
+++ b/assets/data/web/widget.json
@@ -0,0 +1 @@
+[{"id":1,"family":0,"name":"Container","nameCN":"容器组件","lever":5,"linkWidget":"74,85,80,78,70,123","info":"用于容纳单个子组件的容器组件。集成了若干个单子组件的功能,如内外边距、形变、装饰、约束等...","image":"assets/images/widgets/Container.png"},{"id":2,"family":0,"name":"Text","nameCN":"文字组件","lever":5,"linkWidget":"101,324","info":"用于显示文字的组件。拥有的属性非常多,足够满足你的使用需求,核心样式由style属性控制。","image":"assets/images/widgets/Text.png"},{"id":3,"family":0,"name":"Card","nameCN":"卡片组件","lever":3,"linkWidget":"160","info":" 基于Material组件实现,用于将单个组件卡片化。并使其具有投影效果,可加外边距,也可以自定义卡片形状。","image":"assets/images/widgets/Card.png"},{"id":4,"family":0,"name":"FlutterLogo","lever":1,"linkWidget":"","nameCN":"Flutter图标","info":"用于展示Flutter图标组件。可定义颜色、尺寸、展示模式等信息,是一个非常简单的组件。","image":"assets/images/widgets/FlutterLogo.png"},{"id":5,"family":0,"name":"Banner","lever":1,"linkWidget":"","nameCN":"角标组件","info":"用于角标显示的组件。可容纳一个子组件,可选择方位添加角标及信息文字,可设置颜色。","image":"assets/images/widgets/Banner.png"},{"id":6,"family":0,"name":"Icon","lever":2,"linkWidget":"7,30,125","nameCN":"图标组件","info":"用于图标显示的组件。可指定图标资源、大小、颜色。非常简单,但是非常用","image":"assets/images/widgets/Icon.png"},{"id":7,"family":0,"name":"ImageIcon","linkWidget":"6,30,125","nameCN":"容器","lever":1,"info":"用于将一个图片变为纯色的组件。可指定大小、颜色。","image":"assets/images/widgets/ImageIcon.png"},{"id":8,"family":0,"name":"FadeInImage","nameCN":"淡入图片","linkWidget":"38","lever":2,"info":"透明渐变地加载一张图片。可指定占位图片、进退的动画曲线、时间、宽高、fit类型、对齐方式、重复方式等。","image":""},{"id":9,"family":0,"name":"CircleAvatar","nameCN":"圆形组件","linkWidget":"","lever":4,"info":"可将一张图片变成圆形,并且中间可以放置一个组件。可指定半径、前景色、背景色等。","image":""},{"id":10,"family":0,"name":"Visibility","nameCN":"显隐组件","linkWidget":"71","lever":3,"info":"控制一个组件显示或隐藏,可设置隐藏后的占位组件。与其功能相似的由OffStage组件。","image":"assets/images/widgets/Visibility.png"},{"id":11,"family":0,"name":"Chip","nameCN":"小条组件","linkWidget":"12,13,14,15,153","lever":4,"info":"一个横向的圆边小条,可以包含左中右三个组件。可以指定颜色、阴影色和点击事件。","image":"assets/images/widgets/Chip.png"},{"id":12,"family":0,"name":"ChoiceChip","nameCN":"选择小条","lever":3,"linkWidget":"11,13,14,15,153","info":"和Chip组件类似的样式,有一些选择的属性。可以指定选中时的颜色、阴影色和选择事件。","image":"assets/images/widgets/ChoiceChip.png"},{"id":13,"family":0,"name":"ActionChip","nameCN":"事件小条","lever":3,"linkWidget":"11,12,14,15,153","info":"和Chip组件类似的样式,有一些点击的属性。可以指定点击时的阴影深、点击事件。","image":"assets/images/widgets/ActionChip.png"},{"id":14,"family":0,"name":"InputChip","nameCN":"综合小条","linkWidget":"11,12,13,15,153","lever":4,"info":"和Chip组件类似的样式,集成了点击、删除、选择事件为一体。注意:点击事件和选择事件不能同时存在。","image":"assets/images/widgets/InputChip.png"},{"id":15,"family":0,"name":"FilterChip","linkWidget":"11,12,13,14,153","nameCN":"过滤小条","lever":4,"info":"和Chip组件类似的样式,具有选中与否的属性和选中事件。当选中时左侧组件上层会被✔️遮罩。","image":"assets/images/widgets/FilterChip.png"},{"id":16,"family":0,"name":"ListTile","nameCN":"列表瓦片","linkWidget":"162,334","lever":3,"info":"Flutter提供的一个通用列表条目结构,为左中右结构。相应位置可插入组件,可以很方便地应对特定的条目。","image":"assets/images/widgets/ListTile.png"},{"id":17,"family":0,"name":"CheckboxListTile","nameCN":"复选瓦片","linkWidget":"39","lever":3,"info":"Flutter提供的一个通用列表条目结构,为左中结构,尾部是一个CheckBox。相应位置可插入组件,可以很方便地应对特定的条目。","image":"assets/images/widgets/CheckBoxListTile.png"},{"id":18,"family":0,"name":"SwitchListTile","nameCN":"切钮瓦片","linkWidget":"40","lever":3,"info":"Flutter提供的一个通用列表条目结构,为左中结构,尾部是一个Switch。相应位置可插入组件,可以很方便地应对特定的条目。","image":"assets/images/widgets/SwitchListTile.png"},{"id":19,"family":0,"name":"RadioListTile","nameCN":"选钮瓦片","linkWidget":"45","lever":3,"info":"Flutter提供的一个通用列表条目结构,为中右结构,尾部是一个Radio。相应位置可插入组件,可以很方便地应对特定的条目。","image":"assets/images/widgets/RadioListTile.png"},{"id":20,"family":0,"name":"GridTileBar","nameCN":"网格瓦片头","linkWidget":"21","lever":2,"info":"Flutter提供的一个通用头结构,为左中右结构。相应位置可插入组件,可以很方便地应对特定的条目,相比ListTile而言,属性较少。","image":"assets/images/widgets/GridTileBar.png"},{"id":21,"family":0,"name":"GridTile","nameCN":"网格瓦片","linkWidget":"20","lever":3,"info":"Flutter提供的一个通用列表条目结构,可指定头、尾、子组件,常用于网格列表。","image":"assets/images/widgets/GridTile.png"},{"id":22,"family":0,"name":"UserAccountsDrawerHeader","nameCN":"展示头","linkWidget":"154","lever":3.8,"info":"Flutter提供的一个通用展示结构,相应位置可插入组件,可以很方便地应对特定的条目,常用于Drawer中。","image":"assets/images/widgets/UserAccountsDrawerHeader.png"},{"id":23,"family":0,"name":"MaterialButton","nameCN":"材料按钮","linkWidget":"25,26,27,326,175","lever":4,"info":"基于RawMaterialButton实现的通用Material按钮。可盛放一个子组件,能定义颜色、形状等表现,可接收点击和长按事件。","image":""},{"id":24,"family":1,"name":"CupertinoButton","nameCN":"iOS按钮","linkWidget":"23","lever":3,"info":"iOS风格的按钮。可指定颜色、点击时透明度、内边距、圆角等。可接收点击事件。","image":""},{"id":25,"family":0,"name":"FlatButton","nameCN":"平按钮","linkWidget":"24,26,27,175","lever":3,"info":"无阴影的平按钮,基于MaterialButton实现,所有属性和MaterialButton类似。","image":""},{"id":26,"family":0,"name":"RaisedButton","nameCN":"浮起按钮","linkWidget":"24,25,27,175","lever":3,"info":"有阴影的浮起按钮,基于MaterialButton实现,所有属性和MaterialButton类似。","image":""},{"id":27,"family":0,"name":"OutlineButton","nameCN":"线框按钮","linkWidget":"23,24,25,175","lever":3,"info":"边框样式按钮,基于MaterialButton实现,所有属性和MaterialButton类似。","image":""},{"id":28,"family":0,"name":"FloatingActionButton","nameCN":"浮动按钮","linkWidget":"64","lever":4,"info":"浮动按钮,一般用于Scaffold中,可摆放在特定位置。可盛放一个子组件,接收点击、可定义颜色、形状等。","image":""},{"id":29,"family":0,"name":"ButtonBar","nameCN":"按钮栏","linkWidget":"","lever":3,"info":"接收组件列表,常用于盛放若干个按钮。可指定对齐方式、边距等信息。","image":""},{"id":30,"family":0,"name":"IconButton","nameCN":"图标按钮","linkWidget":"6","lever":2,"info":"可点击的图标按钮,可指定图标信息、内边距、大小、颜色等,接收点击事件。","image":""},{"id":31,"family":0,"name":"BackButton","nameCN":"返回按钮","linkWidget":"30","lever":1,"info":"一个具有返回功能的IconButton,返回图标不可更改。在iOS和Android中表现不同","image":""},{"id":32,"family":0,"name":"CloseButton","nameCN":"关闭按钮","linkWidget":"30","lever":1.0,"info":"一个具有关闭功能的IconButton,关闭图标不可更改。","image":""},{"id":33,"family":0,"name":"ToggleButtons","nameCN":"切换按钮组","linkWidget":"332,262","lever":4,"info":"接收组件列表,可指定边线、圆角、颜色等属性。根据具体逻辑,可以实现多个按钮单选或多选的需求。","image":""},{"id":34,"family":0,"name":"Divider","nameCN":"水平分割线","linkWidget":"35,329","lever":2,"info":"水平分割线,可指定颜色、高度、粗细、左右边距信息,常用与列表的item分割线。","image":""},{"id":35,"family":0,"name":"VerticalDivider","nameCN":"竖直分割线","linkWidget":"34,329","lever":2,"info":"竖直分割线,可指定颜色、宽度、粗细、上下边距信息,常用与列表的item分割线。","image":""},{"id":36,"family":0,"name":"Placeholder","nameCN":"占位组件","linkWidget":"","lever":1,"info":"一个矩形和叉叉的占位组件,可指定颜色、线宽、宽高等属性。","image":""},{"id":37,"family":0,"name":"GridPager","nameCN":"网格线组件","linkWidget":"","lever":2,"info":"可容纳一个组件,在其上绘制网格。可指定颜色、线宽、间距等属性。","image":""},{"id":38,"family":1,"name":"Image","nameCN":"图片组件","linkWidget":"8,87","lever":5,"info":"用于显示一张图片,可以从文件、内存、网络、资源里加载。可以指定适应方式、样式、颜色混合模式、重复模式等","image":""},{"id":39,"family":1,"name":"Checkbox","nameCN":"复选框","linkWidget":"17","lever":4,"info":"复选框组件,常用于配置的切换,可指定颜色,接收状态变化回调,也可指定三态。","image":""},{"id":40,"family":1,"name":"Switch","nameCN":"切钮","linkWidget":"41,18","lever":4,"info":"切换选钮,常用于配置的切换,可指定小圆颜色、图片,滑槽颜色等,接收状态变化回调。","image":""},{"id":41,"family":1,"name":"CupertinoSwitch","nameCN":"iOS切钮","linkWidget":"40","lever":3,"info":"iOS风格的切换选钮,常用于配置的切换,可指定颜色,接收状态变化回调。","image":""},{"id":42,"family":1,"name":"Slider","nameCN":"滑块","linkWidget":"43,44,331","lever":4,"info":"滑块组件,可以在指定的最大值和最小值之间拖动选择。可指定颜色、分段数及显示的标签,接收进度变化回调。","image":""},{"id":43,"family":1,"name":"CupertinoSlider","linkWidget":"42","nameCN":"iOS滑块","lever":3,"info":"iOS风格的滑块组件,可以在指定的最大值和最小值之间拖动选择。可指定颜色,接收进度变化回调。","image":""},{"id":44,"family":1,"name":"RangeSlider","nameCN":"范围滑块","linkWidget":"42","lever":4,"info":"范围滑块组件,支持两点拖动,获取之间的范围。可指定颜色、分段数及显示的标签,接收进度变化回调。","image":""},{"id":45,"family":1,"name":"Radio","nameCN":"选钮","linkWidget":"19","lever":4,"info":"由于选中和未选择状态的圆钮,多个Radio根据逻辑可以实现单选或多选的需求。可指定颜色,接收状态变化回调。","image":""},{"id":46,"family":1,"name":"CircularProgressIndicator","nameCN":"圆形进度","linkWidget":"47,48","lever":3,"info":"圆形的进度显示,可指定颜色、线宽、进度等属性。value为null时会不停旋转。","image":""},{"id":47,"family":1,"name":"LinearProgressIndicator","nameCN":"水平进度","linkWidget":"46,48","lever":3,"info":"直线型的进度显示,可指定颜色、进度等属性。value为null时会不停旋转。","image":""},{"id":48,"family":1,"name":"CupertinoActivityIndicator","nameCN":"iOS指示器","linkWidget":"46,47","lever":2,"info":"iOS样式的loading显示组件,可指定半径和是否旋转。","image":""},{"id":49,"family":1,"name":"RefreshIndicator","nameCN":"刷新指示器","linkWidget":"","lever":4,"info":"内部嵌套可滑动区域,下滑时会显示刷新图标,松手后可以执行指定的异步方法。可指定颜色、到顶端距离等属性。","image":""},{"id":50,"family":1,"name":"Tooltip","nameCN":"提示工具","linkWidget":"","lever":3,"info":"由于显示提示信息的组件,长按时显示信息。可指定边距、显示时长、文字样式、装饰灯属性。","image":""},{"id":51,"family":1,"name":"ExpandIcon","nameCN":"展开图标","linkWidget":"66,125","lever":1,"info":"一个展开按钮,点击时会自己执行旋转180的动画。可指定颜色、大小、边距,接收点击事件。","image":""},{"id":52,"family":1,"name":"ExpansionTile","nameCN":"展开瓦片","linkWidget":"178","lever":3,"info":"一个通用的展开栏,可在指定的部位安放组件,点击时会折叠显隐下方组件。接收折叠时事件。","image":""},{"id":53,"family":1,"name":"SelectableText","nameCN":"可选择文字","linkWidget":"2","lever":3,"info":"可选择的文字,可以选择、复制。可指定浮标的颜色、大小、文字样式、对齐方式等。","image":""},{"id":54,"family":1,"name":"TextField","nameCN":"输入框","linkWidget":"199","lever":5,"info":"由于输入的组件,拥有复杂的属性。可指定控制器、文字样式、装饰线、行数限制、游标样式等。接收输入变化、完成输入等事件。","image":""},{"id":55,"family":1,"name":"DropdownButton","nameCN":"下拉按钮","linkWidget":"181","lever":4,"info":"用于下拉选择的按钮,可指定图标、影深、提示等属性,接收选中变化的事件。","image":""},{"id":56,"family":1,"name":"PopupMenuButton","nameCN":"菜单按钮","linkWidget":"174","lever":4,"info":"弹出菜单栏,可指定偏移、颜色、影深、形状等属性。接收item选中的事件和取消选择事件。","image":""},{"id":57,"family":1,"name":"AppBar","nameCN":"应用头栏","linkWidget":"64","lever":4,"info":"一个应用顶部栏的通用结构,可在指定的部位放置相应的组件,常用于Scaffold组件中。","image":""},{"id":58,"family":1,"name":"TabBar","nameCN":"标签栏","linkWidget":"57,59,148","lever":3,"info":"可滑动和点击标签栏,通常用于AppBar的底部,可与TabBarView联用,实现滑页的效果。","image":""},{"id":59,"family":1,"name":"TabBarView","nameCN":"标签页","linkWidget":"58","lever":2,"info":"通常与TabBar联用,实现滑页的效果。一般不单独使用。","image":""},{"id":60,"family":1,"name":"BottomNavigationBar","nameCN":"底部导航","linkWidget":"61","lever":4,"info":"一个底部导航栏,通常用于Scaffold组件的底部,可指定颜色和模式,接受点击回调,可与PageView实现切页效果。","image":""},{"id":61,"family":1,"name":"BottomAppBar","nameCN":"底部导航","linkWidget":"60","lever":4,"info":"一个可凹嵌的底部导航栏,通常用于Scaffold组件的底部,可指定颜色、影深、形状等属性,可与PageView实现切页效果。","image":""},{"id":62,"family":1,"name":"CupertinoNavigationBar","nameCN":"iOS导航","linkWidget":"","lever":3,"info":"一个iOS风格的应用顶部栏的通用结构,可在指定的部位放置相应的组件。可指定背景色、间距、边线等属性。","image":""},{"id":63,"family":1,"name":"CupertinoTabBar","nameCN":"iOS页签","linkWidget":"158","lever":3,"info":"一个iOS风格的TabBar,通常用于CupertinoTabScaffold。可指定颜色、图标大小、边线等数据。接收item的点击事件。","image":""},{"id":64,"family":1,"name":"Scaffold","nameCN":"脚手架","linkWidget":"57,60,61","lever":4,"info":"一个通用app结构,包括上、下、左、右、中、浮动按钮部位,对应位置可盛放组件。","image":""},{"id":65,"family":1,"name":"MaterialApp","nameCN":"Material应用","linkWidget":"64","lever":5,"info":"Material应用的顶级组件,包含路由生成器、主题、语言、主页等属性。","image":""},{"id":66,"family":2,"name":"ClipOval","nameCN":"椭圆裁剪","linkWidget":"67,68,69","lever":3,"info":"可容纳一个子组件,并将其以宽高为长轴和短轴进行椭圆裁切。","image":""},{"id":67,"family":2,"name":"ClipRect","nameCN":"矩形裁剪","linkWidget":"66,68,69","lever":3,"info":"可容纳一个子组件,并将其进行矩形裁切。可借助SizedBox、Align、AspectRadio等限定组件进行定域。","image":""},{"id":68,"family":2,"name":"ClipRRect","nameCN":"圆角矩形裁剪","linkWidget":"66,67,69","lever":3,"info":"可容纳一个子组件,并将其进行圆角矩形裁剪。指定borderRadius作为边角半径。","image":""},{"id":69,"family":2,"name":"ClipPath","nameCN":"路径裁剪","linkWidget":"66,67,68","lever":5,"info":"可容纳一个子组件,并将其按指定路径进行裁剪。可以自定义路径形状,是一个很灵活的裁剪组件。","image":""},{"id":70,"family":2,"name":"DecoratedBox","nameCN":"装饰盒","linkWidget":"1","lever":4,"info":"可容纳一个子组件,可将其进行装饰。核心属性为decoration,可设置边线、渐变、阴影、背景图等。","image":""},{"id":71,"family":2,"name":"Offstage","nameCN":"消失组件","linkWidget":"10","lever":3,"info":"可容纳一个子组件,可更改其的消失与否。offstage属性为true表示隐藏。","image":""},{"id":72,"family":2,"name":"RotatedBox","nameCN":"旋转盒","linkWidget":"90","lever":2,"info":"可容纳一个子组件,将其沿顺时针旋转quarterTurns*90°。","image":""},{"id":73,"family":2,"name":"Opacity","nameCN":"透明化","linkWidget":"89,118","lever":3,"info":"可容纳一个子组件,将其透明度变为opacity值, opacity在0~1之间。","image":""},{"id":74,"family":2,"name":"Padding","nameCN":"边距组件","linkWidget":"1,191","lever":4,"info":"可容纳一个子组件,添加自身内边距来限制孩子组件的占位,核心属性为padding。","image":""},{"id":75,"family":2,"name":"Baseline","nameCN":"基线组件","linkWidget":"2","lever":2,"info":"可容纳一个子组件,通过控制基线高度来控制子组件的位置。一般用于文字组件。","image":""},{"id":76,"family":2,"name":"SizedBox","nameCN":"定尺寸盒","linkWidget":"1","lever":4,"info":"可容纳一个子组件,通过指定宽高限定子组件容身区域。","image":""},{"id":77,"family":2,"name":"AspectRatio","nameCN":"比例盒","linkWidget":"82","lever":3,"info":"可容纳一个子组件,通过指定宽高比aspectRatio,来限定子组件容身区域。","image":""},{"id":78,"family":2,"name":"Transform","nameCN":"变换","linkWidget":"1","lever":4,"info":"可容纳一个子组件,可以通过一个4*4的变换矩阵对子组件进行变换。","image":""},{"id":79,"family":2,"name":"LimitedBox","nameCN":"限制盒","linkWidget":"80","lever":3,"info":"可容纳一个子组件,通过指定最大宽高来限定子组件容身区域。","image":""},{"id":80,"family":2,"name":"ConstrainedBox","nameCN":"约束盒","linkWidget":"1,79,81","lever":3,"info":"可容纳一个子组件,通过指定最大、最小宽高,来限定子组件容身区域。","image":""},{"id":81,"family":2,"name":"UnconstrainedBox","nameCN":"约束盒","linkWidget":"80","lever":3,"info":"可容纳一个子组件,并解除该组件的所有区域约束,展现自我尺寸。","image":""},{"id":82,"family":2,"name":"FractionallySizedBox","nameCN":"分率盒","linkWidget":"77","lever":3,"info":"可容纳一个子组件,指定宽高分率,限定子组件区域为父容器宽高*各分率,及对齐方式alignment。","image":""},{"id":83,"family":2,"name":"OverflowBox","nameCN":"溢出盒","linkWidget":"84","lever":4,"info":"可容纳一个子组件,且子组件允许溢出父组件区域,可以指定宽高的最大最小区域进行限定,拥有对齐属性alignment。","image":""},{"id":84,"family":2,"name":"SizedOverflowBox","nameCN":"尺寸溢出盒","linkWidget":"83","lever":2.8,"info":"可容纳一个子组件,且子组件允许溢出父组件区域,可以通过size属性对子组件进行偏移,拥有对齐属性alignment。","image":""},{"id":85,"family":2,"name":"Align","nameCN":"对齐组件","linkWidget":"1,86,111,120","lever":5,"info":"可容纳一个子组件,可以通过alignment让子组件,定位在父组件宽高的任何指定分率出。","image":""},{"id":86,"family":2,"name":"Center","nameCN":"居中组件","linkWidget":"85","lever":3,"info":"可容纳一个子组件,并使其居中于父组件,是Align组件的一种精简模式。","image":""},{"id":87,"family":2,"name":"FittedBox","nameCN":"适应盒","linkWidget":"38","lever":4,"info":"可容纳一个子组件,使用fit属性决定子组件区域相当于父组件的适应模式,拥有对齐属性alignment。","image":""},{"id":88,"family":2,"name":"ColorFiltered","nameCN":"滤色器","linkWidget":"277,38","lever":5,"info":"可容纳一个子组件,可以并将组件按照29中叠色模式和任意组件混合,强大到我不知道该说什么好。app一键全灰了解一下。","image":""},{"id":89,"family":2,"name":"FadeTransition","nameCN":"透明变换","linkWidget":"73,118","lever":3,"info":"可容纳一个子组件,并使其进行透明度渐变动画,需要提供动画器opacity。","image":""},{"id":90,"family":1,"name":"RotationTransition","nameCN":"旋转变换","linkWidget":"72","lever":3,"info":"可容纳一个子组件,并使其进行旋转动画,需要提供动画器turns,拥有alignment属性。","image":""},{"id":91,"family":1,"name":"ScaleTransition","nameCN":"缩放变换","linkWidget":"","lever":3,"info":"可容纳一个子组件,并使其进行缩放动画,需要提供动画器scale,拥有alignment属性。","image":""},{"id":92,"family":1,"name":"SizeTransition","nameCN":"尺寸变换","linkWidget":"201","lever":3,"info":"可容纳一个子组件,并使其进行尺寸动画,需要提供动画器sizeFactor,可指定尺寸变化轴及轴向的axisAlignment。","image":""},{"id":93,"family":1,"name":"PositionedTransition","nameCN":"位置变换","linkWidget":"97","lever":3,"info":"只能用于Stack中,可容纳一个子组件,让其在两个矩形间进行位置动画,需要提供动画器rect。","image":""},{"id":94,"family":3,"name":"Flex","nameCN":"弹性布局","linkWidget":"95,96,106,107,109","lever":5,"info":"Row和Column的父类,Flutter中最强大的布局方式。可容纳多个组件,可与Spacer、Expended、Flexible组件联用进行灵活布局","image":""},{"id":95,"family":3,"name":"Row","nameCN":"行布局","linkWidget":"94,96","lever":4,"info":"排布方向为横向的Flex布局,可容纳多个组件。其他属性全部一致,详见Flex。","image":""},{"id":96,"family":3,"name":"Column","nameCN":"列布局","linkWidget":"94,95","lever":4,"info":"排布方向为竖向的Flex布局,可容纳多个组件。其他属性全部一致,详见Flex。","image":""},{"id":97,"family":3,"name":"Stack","nameCN":"堆叠布局","linkWidget":"94,95,161","lever":5,"info":"可容纳多个组件,以堆叠的方式摆放子组件,后者居上。拥有alignment属性,可与Positioned组件联合使用,精确定位。","image":""},{"id":98,"family":3,"name":"Wrap","nameCN":"包裹布局","linkWidget":"94,95","lever":5,"info":"可容纳多个组件,按照指定方向依次排布,可以很方便处理孩子的间距,当越界时可以自动换行。拥有主轴和交叉轴的对齐方式,比较灵活。","image":""},{"id":99,"family":3,"name":"Flow","nameCN":"流动布局","linkWidget":"98,94","lever":5,"info":"可容纳多个组件, 需要自己制定排布的代理,可以高强度自定义组件的排布,实现普通布局无法达到的效果。布局王者,当之无愧。","image":""},{"id":100,"family":1,"name":"AnimatedCrossFade","nameCN":"组件切换","linkWidget":"116","lever":5,"info":"将两个组件切换时呈现动画效果,可指定动画曲线、时长、对齐方式等属性。是一个非常有用的组件。","image":""},{"id":101,"family":3,"name":"RichText","nameCN":"富文本","linkWidget":"2","lever":5,"info":"可以容纳多种文字样式或各种组件的富文本组件,应用较为广泛。","image":""},{"id":102,"family":0,"name":"DataTable","nameCN":"数据表格","linkWidget":"110","lever":3,"info":"一个表格组件,可以制订逻辑进行点击、修改、排序等操作。","image":""},{"id":103,"family":1,"name":"Draggable","nameCN":"可拖拽组件","linkWidget":"104,105","lever":4,"info":"可以让组件在界面上任意拖拽,可存放一个泛型T的数据。通常和DragTarget组合使用,来完成拖拽效果。","image":""},{"id":104,"family":1,"name":"DragTarget","nameCN":"拖拽目标","linkWidget":"103,105","lever":4,"info":"一个拖拽的目标区域,可接收Draggable组件的信息。可以获取拖拽时的回调。","image":""},{"id":105,"family":1,"name":"LongPressDraggable","nameCN":"拖拽目标","linkWidget":"103,104","lever":4,"info":"长按时让组件在界面上任意拖拽,可存放一个泛型T的数据。通常和DragTarget组合使用,来完成拖拽效果。","image":""},{"id":106,"family":5,"name":"Expanded","nameCN":"延展组件","linkWidget":"94,109","lever":4,"info":"父类是Flexible,相当于一个fit类型为tight的Flexible组件。可嵌套孩子利用剩余空间对占位空间进行延展。","image":""},{"id":107,"family":0,"name":"Spacer","nameCN":"空间组件","linkWidget":"94","lever":3,"info":"只能用于Row、Column和Flex布局中,可利用剩余空间进行占位,使用flex属性可以给多个Spacer按比例分配空间。","image":""},{"id":108,"family":5,"name":"Positioned","nameCN":"定位组件","linkWidget":"97,159,121","lever":3,"info":"只能用于Stack中,可以指定左上右下的距离对某个组件进行位置精确安放。","image":""},{"id":109,"family":5,"name":"Flexible","nameCN":"灵活组件","linkWidget":"94,106","lever":3,"info":"只能用于只能用于Row、Column和Flex布局中,可嵌套孩子利用剩余空间对占位空间进行延展,也可指定适应类型。","image":""},{"id":110,"family":6,"name":"Table","nameCN":"表格组件","linkWidget":"102","lever":4,"info":"用于展示表格的组件,可指定边线、列宽、文字方向等属性,核心对象类型是TableRow。","image":""},{"id":111,"family":1,"name":"AlignTransition","nameCN":"对齐变换","linkWidget":"85,120","lever":3,"info":"AnimatedWidget的子类,使用Alignment类型的动画器让子组件在两个Alignment对象之间进行过渡动画。","image":""},{"id":112,"family":1,"name":"SlideTransition","nameCN":"滑动变换","linkWidget":"","lever":3,"info":"AnimatedWidget的子类,使用Offset类型的动画器让子组件在两个Offset对象之间进行过渡动画。","image":""},{"id":113,"family":1,"name":"DecoratedBoxTransition","nameCN":"装饰变换","linkWidget":"70","lever":3,"info":"AnimatedWidget的子类,使用Decorated类型的动画器让子组件在两个Decorated对象之间进行过渡动画。","image":""},{"id":114,"family":1,"name":"DefaultTextStyleTransition","nameCN":"文字样式变换","linkWidget":"124,324","lever":3,"info":"AnimatedWidget的子类,使用TextStyle类型的动画器让文字组件在两个TextStyle对象之间进行过渡动画。","image":""},{"id":115,"family":1,"name":"RelativePositionedTransition","nameCN":"矩形位置变换","linkWidget":"70","lever":3,"info":"AnimatedWidget的子类,使用Rect类型的动画器让子组件在两个Rect对象之间进行过渡动画。","image":""},{"id":116,"family":1,"name":"AnimatedSwitcher","nameCN":"动画切换","linkWidget":"100","lever":4,"info":"当子组件变化时执行动画,需要指定子组件的key进行标识。动画方式可以自定义,能指定动画时长、动画曲线等属性。","image":""},{"id":117,"family":1,"name":"AnimatedList","nameCN":"动画列表","linkWidget":"162","lever":3,"info":"强化版的ListView,可以对item进行动画处理。比如在添加、删除是item的动画。","image":""},{"id":118,"family":1,"name":"AnimatedOpacity","nameCN":"透明动画","linkWidget":"89,73","lever":3,"info":"能让子组件进行Opacity(透明度)动画,可指定时长和曲线,有动画结束事件。","image":""},{"id":119,"family":1,"name":"AnimatedPadding","nameCN":"边距动画","linkWidget":"74","lever":3,"info":"能让子组件进行Padding(内边距)动画,可指定时长和曲线,有动画结束事件。","image":""},{"id":120,"family":1,"name":"AnimatedAlign","nameCN":"对齐动画","linkWidget":"85,111","lever":3,"info":"能让子组件进行Align(对齐)动画,可指定时长和曲线,有动画结束事件。","image":""},{"id":121,"family":1,"name":"AnimatedPositioned","nameCN":"定位动画","linkWidget":"108,93,122","lever":3,"info":"能让子组件进行Positioned(定位)动画,可指定时长和曲线,有动画结束事件。只能用于Stack之中。","image":""},{"id":122,"family":1,"name":"AnimatedPositionedDirectional","nameCN":"方向定位动画","linkWidget":"121,159","lever":3,"info":"能让子组件进行PositionedDirectional(方向定位)动画,可指定时长和曲线,有动画结束事件。只能用于Stack之中。","image":""},{"id":123,"family":1,"name":"AnimatedContainer","nameCN":"容器动画","linkWidget":"1","lever":5,"info":"集合alignment、padding、color、decoration、width、height、constraints、margin、transform于一身,这些属性皆可动画,可指定时长和曲线,有动画结束事件。","image":""},{"id":124,"family":1,"name":"AnimatedDefaultTextStyle","nameCN":"容器动画","linkWidget":"114,324","lever":3,"info":"能让子文字组件进行TextStyle(文字样式)动画,可指定时长和曲线,有动画结束事件。","image":""},{"id":125,"family":0,"name":"AnimatedIcon","nameCN":"图标动画","linkWidget":"6","lever":3,"info":"使用AnimatedIcons的图标数据,可以根据一个动画控制器来使图标进行动画效果。可指定图标大小、颜色等。","image":""},{"id":126,"family":0,"name":"Dialog","nameCN":"对话框","linkWidget":"","lever":2,"info":"最简易的对话框面板,包含一个内容组件,可指定影深、背景色、形状等属性。","image":""},{"id":127,"family":0,"name":"AlertDialog","nameCN":"弹出对话框","linkWidget":"129","lever":3,"info":"一个通用的对话框结构,可指定头、中、尾处的组件。拥有标题、内容的文字样式和边距,影深、形状等属性。","image":""},{"id":128,"family":0,"name":"SimpleDialog","nameCN":"简单对话框","linkWidget":"133","lever":3,"info":"一个简单的对话框结构,可指定头、中处的组件。拥有拥有标题、内容的文字样式和边距,影深、形状等属性。常与SimpleDialogOption联用。","image":""},{"id":129,"family":0,"name":"CupertinoAlertDialog","nameCN":"iOS对话框","linkWidget":"127","lever":3,"info":"iOS风格的通用的对话框结构,可指定头、中、尾处的组件。","image":""},{"id":130,"family":0,"name":"AboutDialog","nameCN":"弹出对话框","linkWidget":"193","lever":1,"info":"应用的简介对话框,可指定应用图标、应用名、应用版本号等信息和内部的子组件列表,点击左侧按钮可以跳转到证书页。","image":""},{"id":131,"family":0,"name":"CupertinoActionSheet","nameCN":"iOS行为单","linkWidget":"132","lever":3,"info":"iOS风格的弹出选择结构,可放多的按钮,一般与CupertinoActionSheetAction联用。","image":""},{"id":132,"family":0,"name":"CupertinoActionSheetAction","nameCN":"iOS行为单按键","linkWidget":"131","lever":1,"info":"一个按钮,应用场景很少,通常用于CupertinoActionSheet中,接收点击事件。","image":""},{"id":133,"family":0,"name":"SimpleDialogOption","nameCN":"简单对话框选项","linkWidget":"128","lever":1,"info":"一个按钮,应用场景很少,通常用于SimpleDialog中,接收点击事件。","image":""},{"id":134,"family":0,"name":"DayPicker","nameCN":"日期选择器","linkWidget":"135,136","lever":3,"info":"日期的选择组件,可指定当前日期、选中日期、展示月份等,接收日期选中事件。","image":""},{"id":135,"family":1,"name":"MonthPicker","nameCN":"月份选择器","linkWidget":"134,136","lever":3,"info":"月份的选择组件,自带上下月切换的监听。可指定选择的日期范围、选中日期等,接收日期选中事件。","image":""},{"id":136,"family":1,"name":"YearPicker","nameCN":"年份选择器","linkWidget":"134,135","lever":3,"info":"年份的选择组件,长相比较寒酸。可指定选择的日期范围、选中日期等,接收每份选中事件","image":""},{"id":137,"family":1,"name":"CupertinoDatePicker","nameCN":"iOS日期选择器","linkWidget":"138","lever":3,"info":"高大上的滑滚日期选择器,可指定选择的类型、日期范围等,接收日期选中事件。","image":""},{"id":138,"family":1,"name":"CupertinoTimerPicker","nameCN":"iOS时间选择器","linkWidget":"137","lever":3,"info":"高大上的滑滚时间选择器,可指定选择的类型、初始时间、背景色等,接收时间选中事件。","image":""},{"id":139,"family":1,"name":"CupertinoPicker","nameCN":"iOS选择器","linkWidget":"179","lever":3,"info":"高大上的柱面滑动选择器,精妙十足,可指定很多配置属性,接收滑动时选中事件。","image":""},{"id":140,"family":1,"name":"SnackBar","nameCN":"信息提示条","linkWidget":"141,142","lever":4,"info":"作为组件来说是一个简单的结构组件,可指定形状、影深、背景色等。一般通过ScaffoldState的showSnackBar方法从底部弹出。","image":""},{"id":141,"family":1,"name":"SnackBarAction","nameCN":"信息提示条按钮","linkWidget":"140","lever":1,"info":"一般只用于SnackBar中,接受点击事件。点击一次后该按钮就会被禁用,可以指定颜色和禁用时颜色。","image":""},{"id":142,"family":1,"name":"BottomSheet","nameCN":"底部抽屉","linkWidget":"140","lever":4,"info":"作为组件来说是一个简单的结构组件,可指定形状、影深、背景色、内部组件构造器等。一般通过ScaffoldState的showBottomSheet方法从底部弹出。","image":""},{"id":143,"family":1,"name":"CupertinoContextMenu","nameCN":"ios弹出菜单","linkWidget":"144","lever":5,"info":"一个华丽的iOS风格按钮弹出框,长按时会以动画的形式弹出菜单面板,通常和CupertinoContextMenuAction联用。","image":""},{"id":144,"family":1,"name":"CupertinoContextMenuAction","nameCN":"ios弹出菜单按钮","linkWidget":"143","lever":1,"info":"一般只用于CupertinoContextMenu中的点击按钮。可指定孩子和尾部图标,接收点击事件。","image":""},{"id":145,"family":1,"name":"LicensePage","nameCN":"证书页","linkWidget":"130,193","lever":1,"info":"应用的证书页,可指定应用图标、应用名、应用版本号等信息,其他由Flutter自动生成。","image":""},{"id":146,"family":0,"name":"GestureDetector","nameCN":"手势监听器","linkWidget":"147,150","lever":5,"info":"组件手势事件的检测器,可接受点击、长按、双击,按下、松开、移动等事件,并可以获取触点信息,居家旅行必备组件。","image":""},{"id":147,"family":0,"name":"Listener","nameCN":"事件监听器","linkWidget":"146","lever":3,"info":"组件事件的监听器,可接受按下、松开、移动、取消等事件。较GestureDetector比较原始,可获取的信息也更多。","image":""},{"id":148,"family":0,"name":"Tab","nameCN":"标签","linkWidget":"58","lever":1,"info":"一般用于TabBar中的item,上下结构,可指定图标和一个内容组件。","image":""},{"id":149,"family":1,"name":"InkResponse","nameCN":"水波纹响应","linkWidget":"150,152","lever":1,"info":"水波纹的点击效果,接收点击、双击、长按、取消、高亮变化事件,可指定水波纹颜色、半径、高亮形状等属性。","image":""},{"id":150,"family":1,"name":"InkWell","nameCN":"水波纹","linkWidget":"149,152","lever":4,"info":"InkResponse的子类,基本属性同InkResponse。一个矩形区域的水波纹,可以知道圆角半径,边线形状等。","image":""},{"id":151,"family":1,"name":"TableRowInkWell","nameCN":"表格水波纹","linkWidget":"110","lever":1,"info":"只能用于Table的水波纹,接收点击、双击、长按、高亮变化事件,水波纹会作用于表格的一行。","image":""},{"id":152,"family":1,"name":"Ink","nameCN":"水波","linkWidget":"149,150","lever":3,"info":"使InkWell和InkResponse的水波纹有效,用于绘制图像或其他装饰的Material组件。","image":""},{"id":153,"family":1,"name":"RawChip","nameCN":"原生小条","linkWidget":"11,12,13,14,15","lever":5,"info":"各自Chip组件的始祖,拥有各自Chip表现的能力,支持选中、点击、删除等事件。详见Chip、FilterChip、ActionChip、InputChip、ChoiceChip。","image":""},{"id":154,"family":0,"name":"Drawer","nameCN":"滑页栏","linkWidget":"64,155","lever":2,"info":"一般用于Scaffold中的draw和endDraw属性作为左右的滑页栏,可以容纳一个子组件,能指定影深。","image":""},{"id":155,"family":0,"name":"DrawerHeader","nameCN":"滑页栏","linkWidget":"154","lever":2,"info":"一般用于Drawer中,作为滑页栏的头部。可以指定内外边距、装饰、子组件等属性。","image":""},{"id":156,"family":1,"name":"CupertinoApp","nameCN":"iOS应用","linkWidget":"157,158","lever":4,"info":"iOS风格应用的顶级组件,包含路由生成器、主题、语言、主页等属性。","image":""},{"id":157,"family":1,"name":"CupertinoPageScaffold","nameCN":"iOS页面脚手架","linkWidget":"62","lever":3,"info":"iOS风格的页面布局脚手架结构,可指定顶部的导航栏和页面背景色。","image":""},{"id":158,"family":1,"name":"CupertinoTabScaffold","nameCN":"iOS页签脚手架","linkWidget":"63","lever":3,"info":"iOS风格的页面布局脚手架结构,可指定最底部的导航切换栏可主体内容页。","image":""},{"id":159,"family":0,"name":"PositionedDirectional","nameCN":"方向定位","linkWidget":"108,122","lever":3,"info":"和Positioned组件功能一样,属性名不同。只能用于Stack中,可以指定左上右下的距离对某个组件进行位置精确安放。","image":""},{"id":160,"family":1,"name":"Material","nameCN":"材料组件","linkWidget":"3","lever":5,"info":"Material风格组件的领军人物,灵魂核心。可指定颜色、影深、类型、阴影颜色、形状等属性。","image":""},{"id":161,"family":3,"name":"IndexedStack","nameCN":"索引堆叠","linkWidget":"97","lever":4,"info":"Stack组件的子类,可以堆叠多个组件,并通过index来指定展示的组件索引,其余的会被隐藏。","image":""},{"id":162,"family":0,"name":"ListView","nameCN":"列表组件","linkWidget":"16,163","lever":5,"info":"列表显示的领军人物,容纳多个子组件,可以通过builder、separated、custom等构造。有内边距、是否反向、滑动控制器等属性。","image":""},{"id":163,"family":0,"name":"GridView","nameCN":"网格组件","linkWidget":"21,162","lever":5,"info":"容纳多个组件,并以网格的方式。可以通过count、extent、custom、builder等构造。有内边距、是否反向、滑动控制器等属性。","image":""},{"id":164,"family":0,"name":"SingleChildScrollView","nameCN":"单子滑动","linkWidget":"","lever":5,"info":"使一个组件具有滑动的效果,可指定滑动的方向、是否反向、滑动控制器等属性。","image":""},{"id":165,"family":0,"name":"PageView","nameCN":"滑页","linkWidget":"","lever":5,"info":"容纳多个组件页面,可对它们进行滑动切换,可指定滑动的方向、是否反向、滑动控制器等属性。","image":""},{"id":166,"family":2,"name":"CustomPaint","nameCN":"绘制组件","linkWidget":"","lever":5,"info":"通过CustomPainter进行绘制,可实现一些复杂的自定义绘制组件,是Flutter中自定义组件的灵魂人物。","image":""},{"id":167,"family":5,"name":"MediaQuery","nameCN":"媒体查询","linkWidget":"","lever":4,"info":"可通过MediaQuery.of来获取屏幕尺寸、设备密度、文字缩放比例、边距等信息。","image":""},{"id":168,"family":0,"name":"Theme","nameCN":"主题","linkWidget":"65,169","lever":4,"info":"可通过Theme.of获取ThemeData对象。也可以指定主题应用于Theme的后代组件。","image":""},{"id":169,"family":0,"name":"CupertinoTheme","nameCN":"iOS主题","linkWidget":"156,168","lever":3,"info":"可通过CupertinoTheme.of获取CupertinoThemeData对象。也可以指定主题应用于CupertinoTheme的后代组件。","image":""},{"id":170,"family":1,"name":"WillPopScope","nameCN":"返回拦截","linkWidget":"","lever":5,"info":"当一个界面中有WillPopScope组件时,在页面返回时会触发回调,决定是否返回。可用于二次确认退出的场景。","image":""},{"id":171,"family":1,"name":"Hero","nameCN":"共享动画","linkWidget":"28","lever":5,"info":"可指定标签名,两个界面跳转时具有相同标签的组件会进行共享动画。一个界面中不能存在两个同名的Hero标签","image":""},{"id":172,"family":1,"name":"FutureBuilder","nameCN":"异步构造器","linkWidget":"173","lever":5,"info":"可指定一个Future对象,能够监听异步执行的状态,并在构造器中根据状态构建不同的界面。注意该Future对象不能和FutureBuilder同时创建,否则可能过渡刷新。","image":""},{"id":173,"family":1,"name":"StreamBuilder","nameCN":"流构造器","linkWidget":"172","lever":5,"info":"可指定一个stream对象,能够监听异步执行的状态,并在构造器中根据状态构建不同的界面。","image":""},{"id":174,"family":1,"name":"PopupMenuDivider","nameCN":"弹出菜单分割线","linkWidget":"56,34","lever":1,"info":"PopupMenuButton的分割线,一般不单独使用,可指定高度。","image":""},{"id":175,"family":1,"name":"RawMaterialButton","nameCN":"原始按钮","linkWidget":"23,25,26,27","lever":5,"info":"原始的Material按钮,按钮界的幕后大佬,可接受点击、长按、高亮变化事件,可指定颜色、形状。影深、内边距等属性。","image":""},{"id":176,"family":1,"name":"Dismissible","nameCN":"滑动消失","linkWidget":"162","lever":4,"info":"滑动时可显示底部组件,可指定滑动的方向和交叉轴的偏移量。接收确认消失和消失时的回调。","image":""},{"id":177,"family":1,"name":"ReorderableListView","nameCN":"可重排序列表","linkWidget":"162","lever":4,"info":"可以进行长按排序的ListView,可指定滑动方向、是否反向、滑动控制器等属性。","image":""},{"id":178,"family":1,"name":"ExpansionPanelList","nameCN":"展开列表","linkWidget":"52","lever":3,"info":"可展开的列表组件,可根据逻辑来实现单展开或多展开。可指定展开动画时长,接收展开回调","image":""},{"id":179,"family":1,"name":"ListWheelScrollView","nameCN":"滚轮列表","linkWidget":"139","lever":4,"info":"高大上的柱面滑动列表,精妙十足,可指定item高度、透视、挤压等属性,接收滑动时选中事件。","image":""},{"id":180,"family":5,"name":"ScrollConfiguration","nameCN":"ios菜单按钮","linkWidget":"162,163,164","lever":3,"info":"需要包裹一个可滑动的组件,并通过behavior属性控制滑动的效果,可以去除滑动的蓝色阴影等。","image":""},{"id":181,"family":5,"name":"DropdownButtonHideUnderline","nameCN":"下拉按钮隐藏线","linkWidget":"55","lever":1,"info":"用于去除DropdownButton的下划线,本身没有什么应用价值。","image":""},{"id":182,"family":1,"name":"Overlay","nameCN":"悬浮组件","linkWidget":"","lever":5,"info":"可以将组件在全应用中进行悬浮显示,能够添加或移除组件,它们有独立管理的栈。","image":""},{"id":183,"family":4,"name":"CustomScrollView","nameCN":"通用滑动视图","linkWidget":"184,185,188","lever":5,"info":"一个通用的滑动结构,可以指定滑动方向、是否反向、滑动控制器等属性。其中包含的子组件们必须是Sliver家族。","image":""},{"id":184,"family":4,"name":"SliverAppBar","nameCN":"Sliver头部栏","linkWidget":"183,196","lever":4,"info":"Sliver家族的顶部栏通用结构,可以指定左中右组件、收缩空间、影深、固定模式、背景色等属性。","image":""},{"id":185,"family":4,"name":"SliverList","nameCN":"Sliver列表","linkWidget":"183,186,187","lever":5,"info":"Sliver家族的列表组件,通过指定delegate构造子组件。通常用于CustomScrollView中。","image":""},{"id":186,"family":4,"name":"SliverFixedExtentList","nameCN":"Sliver固定延展列表","linkWidget":"183,185,187","lever":3,"info":"Sliver家族的列表组件,通过delegate构造子组件,可以指定item的高度。通常用于CustomScrollView中。","image":""},{"id":187,"family":4,"name":"SliverFillViewport","nameCN":"Sliver填充视图列表","linkWidget":"183,185,186","lever":3,"info":"Sliver家族的列表组件,通过delegate构造子组件,item的高度会填空视口,可以指定是否的分率。","image":""},{"id":188,"family":4,"name":"SliverGird","nameCN":"Sliver网格","linkWidget":"183","lever":4,"info":"Sliver家族的网格列表组件,和GirdView类似,通过count和extent构造。通常用于CustomScrollView中。","image":""},{"id":189,"family":4,"name":"SliverToBoxAdapter","nameCN":"Sliver适配器","linkWidget":"183","lever":4,"info":"可以容纳一个普通的组件,并将其转化成Sliver家族组件的适配器。","image":""},{"id":190,"family":4,"name":"SliverPersistentHeader","nameCN":"Sliver存留头","linkWidget":"183","lever":5,"info":"通常用于CustomScrollView中,可以让一个组件在滑动中停留在顶部,不会滑动消失。","image":""},{"id":191,"family":4,"name":"SliverPadding","nameCN":"Sliver内间距","linkWidget":"74","lever":3,"info":"可容纳一个Sliver家族的子组件,添加自身内边距来限制孩子组件的占位,核心属性为padding。","image":""},{"id":192,"family":4,"name":"SliverOpacity","nameCN":"Sliver透明度","linkWidget":"73","lever":3,"info":"可容纳一个Sliver家族的子组件,并通过opacity来指定子组件的透明度。","image":""},{"id":193,"family":0,"name":"AboutListTile","nameCN":"关于应用条目","linkWidget":"130,145","lever":3,"info":"一个点击条目,点击时可以弹出应用相关信息,可指定应用图标、应用名、应用版本号等信息和内部的子组件列表。","image":""},{"id":194,"family":1,"name":"Scrollbar","nameCN":"滑动指示栏","linkWidget":"195,164,162","lever":3,"info":"需要包裹一个可滑动区域,当可滑动时,会显示滑动的bar用于指示。","image":""},{"id":195,"family":1,"name":"CupertinoScrollbar","nameCN":"iOS滑动指示栏","linkWidget":"194,164,162","lever":3,"info":"iOS风格的滑动指示栏,需要包裹一个可滑动区域,当可滑动时,会显示滑动的bar用于指示。","image":""},{"id":196,"family":4,"name":"FlexibleSpaceBar","nameCN":"ios菜单按钮","linkWidget":"184","lever":3,"info":"通常用于SliverAppBar中的可伸展区域,可指定标题、标题间距、背景、折叠模式等。","image":""},{"id":197,"family":6,"name":"ErrorWidget","nameCN":"错误组件","linkWidget":"","lever":1,"info":"用于显示一个错误信息的组件,红底黄字,在开发过程中经常看到,一般不使用。","image":""},{"id":198,"family":1,"name":"Form","nameCN":"表单组件","linkWidget":"199","lever":4,"info":"表单组件,可以接收其下的FormField组件的变化回调,通过onWillPop拦截页面返回,通过FormState可对表单字段进行保存或校验。","image":""},{"id":199,"family":1,"name":"TextFormField","nameCN":"文字表单输入","linkWidget":"54,198","lever":4,"info":"和TextField属性基本一致,在其基础上增加字段的校验和提交的回调,FormState的save会触发onSaved回调。","image":""},{"id":200,"family":1,"name":"Stepper","nameCN":"步骤组件","linkWidget":"","lever":5,"info":"步骤组件,可指定一步步的操作,可以自定义步骤的内容,确认和返回的按钮以及步骤排列的方向。","image":""},{"id":201,"family":1,"name":"AnimatedSize","nameCN":"尺寸动画","linkWidget":"92","lever":3,"info":"子组件大小发生变化是,进行动画渐变,可指定时长、对齐方式、曲线、vsync等属性。","image":""},{"id":202,"family":0,"name":"Builder","nameCN":"构造器","linkWidget":"","lever":2,"info":"一个不影响子组件占位空间,不具有显示性的组件,存在的唯一价值是提供当前组件对应元素的上下文。","image":""},{"id":203,"family":0,"name":"OrientationBuilder","nameCN":"方向构造器","linkWidget":"202","lever":2,"info":"能够回调父组件是横向还是纵向,可以据此来构建不同的子组件。","image":""},{"id":204,"family":0,"name":"PreferredSize","nameCN":"优先尺寸","linkWidget":"57,64","lever":2,"info":"实现了PreferredSizeWidget接口,可容纳一个子组件,设置优先尺寸,不会对其子组件施加任何约束。","image":""},{"id":205,"family":0,"name":"TabPageSelector","nameCN":"页签滑动选择器","linkWidget":"206,59","lever":2,"info":"通常作为指示器与TabBarView联用,共同使用一个TabController。可指定颜色、大小、选中色。","image":""},{"id":206,"family":0,"name":"TabPageSelectorIndicator","nameCN":"页签指示器","linkWidget":"205","lever":2,"info":"一个有边线的圆形组件,可指定大小、颜色、边线色。是TabPageSelector的部分之一,一般不单独使用。","image":""},{"id":208,"family":0,"name":"Title","nameCN":"应用标题","linkWidget":"65","lever":2,"info":"该组件用于描述app在操作系统中的名称,可以在应用栏列表里看到效果。MaterialApp中的title字段效果的根源是该组件。","image":""},{"id":211,"family":0,"name":"MaterialBanner","nameCN":"横幅组件","linkWidget":"","lever":2,"info":"Material风格的横幅组件,支持左中右或左中下结构,可指定边距背景色等","image":""},{"id":214,"family":0,"name":"NavigationToolbar","nameCN":"导航工具条","linkWidget":"57","lever":2,"info":"左中右模式的通用结构组件,可指定中间组件距左侧边距及是否居中。源码在AppBar等导航条结构中有使用它。","image":""},{"id":218,"family":0,"name":"CupertinoNavigationBarBackButton","nameCN":"iOS风格返回按钮","linkWidget":"57","lever":2,"info":"Cupertino风格的导航栏返回按钮,可指定颜色和点击事件,一般不单独使用。","image":""},{"id":231,"family":1,"name":"InputDecorator","nameCN":"输入装饰","linkWidget":"54","lever":2,"info":"在外层包裹输入的装饰,是TextField的底层核心组件之一,一般不单独使用。","image":""},{"id":232,"family":1,"name":"Navigator","nameCN":"导航器","linkWidget":"65","lever":4,"info":"Navigator用堆栈规则管理一组子组件,可以将子组件切入弹出及监听出入栈事件。MaterialApp路由管理的本源就是使用了Navigator。","image":""},{"id":244,"family":1,"name":"EditableText","nameCN":"可编辑文字","linkWidget":"2,54","lever":2,"info":"可以编辑的文字,是TextField的底层最核心组件,一般不单独使用。","image":""},{"id":245,"family":1,"name":"CupertinoTextField","nameCN":"iOS风格输入框","linkWidget":"54","lever":4,"info":"Cupertino风格的输入框,属性和TextField类似,可指定控制器、文字样式、装饰线、行数限制、游标样式等。接收输入变化、完成输入等事件。","image":""},{"id":251,"family":4,"name":"NestedScrollView","nameCN":"嵌套滑动视图","linkWidget":"183","lever":4,"info":"用于多个视图滑动嵌套处理,可以指定头部、滑动控制器、滑动方向等,其中body必须是可滑动类型的组件。","image":""},{"id":253,"family":1,"name":"Scrollable","nameCN":"可滑动组件","linkWidget":"340,349","lever":4,"info":"实现了一个可滚动组件的交互模型,需要viewportBuilder进的viewport的构造。是ScrollView的核心实现组件之一,一般不直接使用。","image":""},{"id":255,"family":1,"name":"ValueListenableBuilder","nameCN":"监听值构造器","linkWidget":"","lever":5,"info":"可以监听一个值,当其变化时通过builder回调能重建界面,避免使用setState刷新。","image":""},{"id":262,"family":1,"name":"CupertinoSegmentedControl","nameCN":"iOS多栏切换","linkWidget":"33","lever":4,"info":"iOS风格的多按钮栏,表现和ToggleButtons类似,可指定内边距。","image":""},{"id":263,"family":2,"name":"FractionalTranslation","nameCN":"分度偏移","linkWidget":"","lever":3,"info":"通过offset属性将子组件进行偏移,偏移量为OffSet横纵*子组件大小。","image":""},{"id":264,"family":2,"name":"RepaintBoundary","nameCN":"重绘边界","linkWidget":"166","lever":5,"info":"为子组件创建一个单独的显示列表,提升性能。源码中在TextField、DrawerController、Scrollbar、Sliver等组件中均有应用","image":""},{"id":277,"family":2,"name":"ShaderMask","nameCN":"着色器遮罩","linkWidget":"88,38","lever":4,"info":"可容纳一个孩子,并通过着色器来对孩子进行着色,可指定混色模式。通常用于组件渐变色处理。","image":""},{"id":278,"family":2,"name":"BackdropFilter","nameCN":"背景滤镜","linkWidget":"88,97,67","lever":4,"info":"可容纳一个孩子,并将背景进行模糊滤镜。可以通过Stack将背景模糊实现组件的模糊效果。","image":""},{"id":279,"family":2,"name":"PhysicalShape","nameCN":"物理形状","linkWidget":"69","lever":4,"info":"可以让子组件按照路径进行剪裁,并且可以指定背景色、影深、阴影颜色、剪切行为。","image":""},{"id":285,"family":2,"name":"CustomSingleChildLayout","nameCN":"通用单子布局","linkWidget":"341","lever":3,"info":"可容纳一个子组件,并指定代理类对子组件进行排布。代理类可获取父容器区域和子组件的区域大小,及区域约束情况。","image":""},{"id":287,"family":2,"name":"LayoutBuilder","nameCN":"布局构造器","linkWidget":"","lever":4,"info":"可以检测到父容器的区域大小,并根据父容器的尺寸信息可以完成自定义布局。是一个非常实用的布局组件。","image":""},{"id":292,"family":2,"name":"IgnorePointer","nameCN":"忽视点击","linkWidget":"295,146,149,150","lever":4,"info":"容纳一个子组件,可以通过指定ignoring属性,来决定孩子是否忽略手势事件,其本身不接受事件。","image":""},{"id":293,"family":1,"name":"MouseRegion","nameCN":"鼠标区域","linkWidget":"","lever":3,"info":"用于鼠标事件监听的组件,通常用于桌面和Web平台,可监听鼠标的移入、移除、移动事件。","image":""},{"id":295,"family":2,"name":"AbsorbPointer","nameCN":"吸收点击","linkWidget":"146,149,150,292","lever":4,"info":"容纳一个子组件,可以通过指定ignoring属性,来决定孩子是否忽略手势事件,其本身接受事件。","image":""},{"id":297,"family":2,"name":"IntrinsicWidth","nameCN":"固有宽","linkWidget":"298","lever":4,"info":"根据子元素的固有宽度度调整其子元素大小的组件,可解决很多布局的疑难杂症,但相对昂贵。","image":""},{"id":298,"family":2,"name":"IntrinsicHeight","nameCN":"固有高","linkWidget":"297","lever":4,"info":"根据子元素的固有高度调整其子元素大小的组件,可解决很多布局的疑难杂症,但相对昂贵。","image":""},{"id":307,"family":4,"name":"SliverOverlapAbsorber","nameCN":"重叠吸收器","linkWidget":"251,308","lever":3,"info":"包裹另一个的sliver,并迫使其布局范围被视为重叠。需要和SliverOverlapInjector联用。","image":""},{"id":308,"family":4,"name":"SliverOverlapInjector","nameCN":"重叠注射器","linkWidget":"251,307","lever":3,"info":"一个sliver,需要和SliverOverlapAbsorber联用,处理视图重叠问题。","image":""},{"id":312,"family":6,"name":"PerformanceOverlay","nameCN":"性能浮层","linkWidget":"65","lever":2,"info":"可以非常方便地开启性能监测的两个柱图,方便查看刷新界面时帧率的变化情况。","image":""},{"id":313,"family":6,"name":"RawImage","nameCN":"原图片","linkWidget":"38","lever":2,"info":"是实现Image组件的核心组件,可以显示ui的Image,基本属性同Image,一般很少单独使用。","image":""},{"id":315,"family":5,"name":"LayoutId","nameCN":"布局Id","linkWidget":"341","lever":2,"info":"只能用于CustomMultiChildLayout组件中,为其子组件标识身份。","image":""},{"id":324,"family":5,"name":"DefaultTextStyle","nameCN":"默认字体样式","linkWidget":"2,114,124","lever":3,"info":"可容纳一个孩子,为后代的文字指定默认样式。常用于多个相同文字的样式统一,避免一一设置。","image":""},{"id":325,"family":5,"name":"IconTheme","nameCN":"图标样式","linkWidget":"6","lever":3,"info":"可容纳一个孩子,为后代的图标指定默认样式。常用于多个相同图标的样式统一,避免一一设置。","image":""},{"id":326,"family":5,"name":"ButtonTheme","nameCN":"按钮样式","linkWidget":"23,25,26,27","lever":3,"info":"主要用于为后代的Button类型组件统一设置默认属性,也可以通过该组件获取默认Button的属性。","image":""},{"id":327,"family":5,"name":"MaterialBannerTheme","nameCN":"横幅样式","linkWidget":"211","lever":2,"info":"主要用于为后代的MaterialBanner组件统一设置默认属性,也可以通过该组件获取默认MaterialBanner的属性。","image":""},{"id":328,"family":5,"name":"ChipTheme","nameCN":"小条样式","linkWidget":"11,153,12,13,14,15","lever":3,"info":"主要用于为后代的Chip类型组件统一设置默认属性,也可以通过该组件获取默认Chip的属性。","image":""},{"id":329,"family":5,"name":"DividerTheme","nameCN":"分割线样式","linkWidget":"34,35","lever":3,"info":"主要用于为后代的Divider类型组件统一设置默认属性,也可以通过该组件获取默认Divider的属性。","image":""},{"id":330,"family":5,"name":"PopupMenuTheme","nameCN":"弹出菜单样式","linkWidget":"56","lever":2,"info":"主要用于为后代的PopupMenuButton组件统一设置默认属性,也可以通过该组件获取默认PopupMenu的属性。","image":""},{"id":331,"family":5,"name":"SliderTheme","nameCN":"滑块样式","linkWidget":"42","lever":3,"info":"可容纳一个孩子,为后代的Slider指定默认样式。常用于Slider的样式统一,避免一一设置,也可以对Slider进行样式定制。","image":""},{"id":332,"family":5,"name":"ToggleButtonsTheme","nameCN":"滑块样式","linkWidget":"33","lever":2,"info":"主要用于为后代的ToggleButtons组件统一设置默认属性,也可以通过该组件获取默认ToggleButtons的属性。","image":""},{"id":333,"family":5,"name":"TooltipTheme","nameCN":"提示主题","linkWidget":"50","lever":2,"info":"主要用于为后代的Tooltip组件统一设置默认属性,也可以通过该组件获取默认TooltipTheme的属性。","image":""},{"id":334,"family":5,"name":"ListTileTheme","nameCN":"ListTile主题","linkWidget":"16","lever":2,"info":"主要用于为后代的ListTile组件统一设置默认属性,也可以通过该组件获取默认ListTile的属性。","image":""},{"id":338,"family":5,"name":"ButtonBarTheme","nameCN":"按钮条主题","linkWidget":"29","lever":2,"info":"主要用于为后代的ButtonBar组件统一设置默认属性,也可以通过该组件获取默认ButtonBarTheme的属性。","image":""},{"id":340,"family":3,"name":"Viewport","nameCN":"视口组件","linkWidget":"253,349","lever":1,"info":"通常用于为滑动视图提供视口,仅构建显示和预加载的部位。可指定预加载的长度、滑动轴向等。是ScrollView的核心实现组件之一,一般不直接使用。","image":""},{"id":341,"family":3,"name":"CustomMultiChildLayout","nameCN":"通用多子布局","linkWidget":"315,285","lever":4,"info":"使用一个代理类对子组件集进行布局控制,子组件必须使用LayoutId组件进行标识。","image":""},{"id":342,"family":3,"name":"ListBody","nameCN":"列表体","linkWidget":"162","lever":1,"info":"将若干子组件按照轴向进行排列,可设置的属性很少,一般很少使用,而选择使用ListView。","image":""},{"id":351,"family":1,"name":"InteractiveViewer","nameCN":"交互视图","linkWidget":"147,146,78","lever":4,"info":"主要对移动、缩放等手势交互进行封装,简化使用,可指定移动边界、缩放比例、手势监听等。","image":""},{"id":352,"family":0,"name":"CupertinoDialogAction","nameCN":"交互视图","linkWidget":"129","lever":1,"info":" 一个简单的按钮,通常用于CupertinoAlertDialog中,一般不单独使用。","image":""}]
\ No newline at end of file
diff --git a/assets/flutter.db b/assets/flutter.db
index 9cdba0a2c..4ca299955 100644
Binary files a/assets/flutter.db and b/assets/flutter.db differ
diff --git a/assets/fonts/CHOPS.TTF b/assets/fonts/CHOPS.ttf
similarity index 100%
rename from assets/fonts/CHOPS.TTF
rename to assets/fonts/CHOPS.ttf
diff --git a/assets/images/caver.webp b/assets/images/caver.webp
index 426ab0ccb..3d4102c05 100644
Binary files a/assets/images/caver.webp and b/assets/images/caver.webp differ
diff --git a/assets/images/coffee_wx.webp b/assets/images/coffee_wx.webp
new file mode 100644
index 000000000..34298068b
Binary files /dev/null and b/assets/images/coffee_wx.webp differ
diff --git a/assets/images/coffee_wx_ac.webp b/assets/images/coffee_wx_ac.webp
new file mode 100644
index 000000000..1d21f46fe
Binary files /dev/null and b/assets/images/coffee_wx_ac.webp differ
diff --git a/assets/images/coffee_zfb.webp b/assets/images/coffee_zfb.webp
new file mode 100644
index 000000000..79859859c
Binary files /dev/null and b/assets/images/coffee_zfb.webp differ
diff --git a/assets/images/widgets/Autocomplete.svg b/assets/images/widgets/Autocomplete.svg
new file mode 100644
index 000000000..653b4f5a1
--- /dev/null
+++ b/assets/images/widgets/Autocomplete.svg
@@ -0,0 +1,30 @@
+
\ No newline at end of file
diff --git a/assets/images/widgets/Banner.svg b/assets/images/widgets/Banner.svg
new file mode 100644
index 000000000..27c390ff1
--- /dev/null
+++ b/assets/images/widgets/Banner.svg
@@ -0,0 +1,13 @@
+
diff --git a/assets/images/widgets/Card.svg b/assets/images/widgets/Card.svg
new file mode 100644
index 000000000..62d2d4b8d
--- /dev/null
+++ b/assets/images/widgets/Card.svg
@@ -0,0 +1,17 @@
+
diff --git a/assets/images/widgets/Card.webp b/assets/images/widgets/Card.webp
deleted file mode 100644
index 9f8452a43..000000000
Binary files a/assets/images/widgets/Card.webp and /dev/null differ
diff --git a/assets/images/widgets/Chip.svg b/assets/images/widgets/Chip.svg
new file mode 100644
index 000000000..a66547522
--- /dev/null
+++ b/assets/images/widgets/Chip.svg
@@ -0,0 +1,28 @@
+
diff --git a/assets/images/widgets/Chip.webp b/assets/images/widgets/Chip.webp
deleted file mode 100644
index 1be3bfa81..000000000
Binary files a/assets/images/widgets/Chip.webp and /dev/null differ
diff --git a/assets/images/widgets/CircleAvatar.svg b/assets/images/widgets/CircleAvatar.svg
new file mode 100644
index 000000000..eafafcb46
--- /dev/null
+++ b/assets/images/widgets/CircleAvatar.svg
@@ -0,0 +1,13 @@
+
diff --git a/assets/images/widgets/Container.svg b/assets/images/widgets/Container.svg
new file mode 100644
index 000000000..c1500829f
--- /dev/null
+++ b/assets/images/widgets/Container.svg
@@ -0,0 +1,23 @@
+
diff --git a/assets/images/widgets/Container.webp b/assets/images/widgets/Container.webp
deleted file mode 100644
index 0cc509a9a..000000000
Binary files a/assets/images/widgets/Container.webp and /dev/null differ
diff --git a/assets/images/widgets/FilterChip.svg b/assets/images/widgets/FilterChip.svg
new file mode 100644
index 000000000..2c0214a26
--- /dev/null
+++ b/assets/images/widgets/FilterChip.svg
@@ -0,0 +1,33 @@
+
diff --git a/assets/images/widgets/FloatingActionButton.svg b/assets/images/widgets/FloatingActionButton.svg
new file mode 100644
index 000000000..dfe232950
--- /dev/null
+++ b/assets/images/widgets/FloatingActionButton.svg
@@ -0,0 +1,4 @@
+
diff --git a/assets/images/widgets/FlutterLogo.svg b/assets/images/widgets/FlutterLogo.svg
new file mode 100644
index 000000000..6a82787f7
--- /dev/null
+++ b/assets/images/widgets/FlutterLogo.svg
@@ -0,0 +1,6 @@
+
diff --git a/assets/images/widgets/GestureDetector.svg b/assets/images/widgets/GestureDetector.svg
new file mode 100644
index 000000000..8d3a00012
--- /dev/null
+++ b/assets/images/widgets/GestureDetector.svg
@@ -0,0 +1,5 @@
+
diff --git a/assets/images/widgets/GridView.svg b/assets/images/widgets/GridView.svg
new file mode 100644
index 000000000..2d7f6874a
--- /dev/null
+++ b/assets/images/widgets/GridView.svg
@@ -0,0 +1,12 @@
+
diff --git a/assets/images/widgets/Icon.svg b/assets/images/widgets/Icon.svg
new file mode 100644
index 000000000..dd64950cb
--- /dev/null
+++ b/assets/images/widgets/Icon.svg
@@ -0,0 +1,21 @@
+
diff --git a/assets/images/widgets/Image.svg b/assets/images/widgets/Image.svg
new file mode 100644
index 000000000..e69de29bb
diff --git a/assets/images/widgets/InputChip.svg b/assets/images/widgets/InputChip.svg
new file mode 100644
index 000000000..d50adf71c
--- /dev/null
+++ b/assets/images/widgets/InputChip.svg
@@ -0,0 +1,35 @@
+
diff --git a/assets/images/widgets/InputChip.webp b/assets/images/widgets/InputChip.webp
deleted file mode 100644
index c6bb78834..000000000
Binary files a/assets/images/widgets/InputChip.webp and /dev/null differ
diff --git a/assets/images/widgets/ListView.svg b/assets/images/widgets/ListView.svg
new file mode 100644
index 000000000..4e10e6580
--- /dev/null
+++ b/assets/images/widgets/ListView.svg
@@ -0,0 +1,19 @@
+
diff --git a/assets/images/widgets/MaterialButton.svg b/assets/images/widgets/MaterialButton.svg
new file mode 100644
index 000000000..11b59f54b
--- /dev/null
+++ b/assets/images/widgets/MaterialButton.svg
@@ -0,0 +1,13 @@
+
diff --git a/assets/images/widgets/PageView.svg b/assets/images/widgets/PageView.svg
new file mode 100644
index 000000000..5dc3a701d
--- /dev/null
+++ b/assets/images/widgets/PageView.svg
@@ -0,0 +1,24 @@
+
\ No newline at end of file
diff --git a/assets/images/widgets/RichText.svg b/assets/images/widgets/RichText.svg
new file mode 100644
index 000000000..0dd5f661a
--- /dev/null
+++ b/assets/images/widgets/RichText.svg
@@ -0,0 +1,6 @@
+
diff --git a/assets/images/widgets/SingleChildScrollView.svg b/assets/images/widgets/SingleChildScrollView.svg
new file mode 100644
index 000000000..baddde13b
--- /dev/null
+++ b/assets/images/widgets/SingleChildScrollView.svg
@@ -0,0 +1,43 @@
+
diff --git a/assets/images/widgets/Text.png b/assets/images/widgets/Text.png
new file mode 100644
index 000000000..5f690258f
Binary files /dev/null and b/assets/images/widgets/Text.png differ
diff --git a/assets/images/widgets/Text.svg b/assets/images/widgets/Text.svg
new file mode 100644
index 000000000..2b327a5de
--- /dev/null
+++ b/assets/images/widgets/Text.svg
@@ -0,0 +1,5 @@
+
diff --git a/assets/images/widgets/Widget.svg b/assets/images/widgets/Widget.svg
new file mode 100644
index 000000000..f92990967
--- /dev/null
+++ b/assets/images/widgets/Widget.svg
@@ -0,0 +1,8 @@
+
diff --git a/assets/images/wxgzh.webp b/assets/images/wxgzh.webp
new file mode 100644
index 000000000..0a44c72cc
Binary files /dev/null and b/assets/images/wxgzh.webp differ
diff --git a/assets/version.json b/assets/version.json
index 79dcc07ab..0c311e970 100644
--- a/assets/version.json
+++ b/assets/version.json
@@ -1,3 +1,3 @@
{
- "dbVersion": 2
+ "dbVersion": 5
}
\ No newline at end of file
diff --git a/desiredFileName.txt b/desiredFileName.txt
new file mode 100644
index 000000000..9e26dfeeb
--- /dev/null
+++ b/desiredFileName.txt
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/devtools_options.yaml b/devtools_options.yaml
new file mode 100644
index 000000000..fa0b357c4
--- /dev/null
+++ b/devtools_options.yaml
@@ -0,0 +1,3 @@
+description: This file stores settings for Dart & Flutter DevTools.
+documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
+extensions:
diff --git a/doc/development/architecture.md b/doc/development/architecture.md
new file mode 100644
index 000000000..65c14cf2b
--- /dev/null
+++ b/doc/development/architecture.md
@@ -0,0 +1,247 @@
+# FlutterUnit 架构设计文档
+
+## 项目概述
+
+FlutterUnit 是一个全平台的 Flutter 组件展示和学习应用,支持 Android、iOS、Web、Windows、macOS 和 Linux 平台。项目采用模块化架构,提供了 300+ Flutter 组件的详细展示、代码示例和交互演示。
+
+## 技术栈
+
+- **框架**: Flutter 3.35.1
+- **状态管理**: flutter_bloc (BLoC 模式)
+- **路由管理**: go_router
+- **数据库**: SQLite (本地数据存储)
+- **网络请求**: dio
+- **国际化**: flutter_localizations
+- **UI组件**: 自研 TolyUI 组件库
+
+## 整体架构
+
+### 分层架构
+
+```
+┌─────────────────────────────────────┐
+│ Presentation Layer │ ← UI层 (Views/Pages)
+├─────────────────────────────────────┤
+│ Business Logic Layer │ ← 业务逻辑层 (BLoC)
+├─────────────────────────────────────┤
+│ Repository Layer │ ← 仓储层 (Repository)
+├─────────────────────────────────────┤
+│ Data Source Layer │ ← 数据源层 (Database/API)
+└─────────────────────────────────────┘
+```
+
+### 模块化设计
+
+```
+FlutterUnit/
+├── modules/
+│ ├── basic_system/ # 基础系统模块
+│ │ ├── app/ # 应用核心配置
+│ │ ├── app_update/ # 应用更新
+│ │ ├── authentication/ # 用户认证
+│ │ ├── components/ # 通用组件
+│ │ ├── l10n/ # 国际化
+│ │ ├── storage/ # 数据存储
+│ │ ├── toly_ui/ # UI组件库
+│ │ └── utils/ # 工具类
+│ ├── widget_system/ # 组件系统模块
+│ │ ├── widget_module/ # 组件业务逻辑
+│ │ ├── widget_repository/ # 组件数据仓储
+│ │ └── widget_ui/ # 组件UI展示
+│ ├── knowledge_system/ # 知识系统模块
+│ │ ├── algorithm/ # 算法相关
+│ │ ├── artifact/ # 工件管理
+│ │ ├── awesome/ # 精选内容
+│ │ ├── layout/ # 布局相关
+│ │ └── note/ # 笔记功能
+│ ├── painting_system/ # 绘制系统模块
+│ │ └── draw_system/ # 自定义绘制
+│ └── tools_system/ # 工具系统模块
+│ └── treasure_tools/ # 实用工具集
+└── lib/
+ ├── src/
+ │ ├── navigation/ # 路由导航
+ │ ├── l10n/ # 本地化
+ │ └── starter/ # 应用启动
+ └── main.dart
+```
+
+## 核心架构组件
+
+### 1. 应用启动器 (FxApplication)
+
+```dart
+class FxApplication with FxStarter {
+ @override
+ Widget get app => const AppBlocProvider(child: FlutterUnit3());
+
+ @override
+ AppStartRepository get repository => const FlutterUnitStartRepo();
+}
+```
+
+**职责**:
+- 应用启动流程管理
+- 全局配置初始化
+- 错误处理和监控
+
+### 2. 状态管理 (BLoC 模式)
+
+```
+Event → BLoC → State → UI
+ ↑ ↓
+ └── User Interaction ┘
+```
+
+**主要 BLoC**:
+- `AppConfigBloc`: 应用配置管理
+- `WidgetsBloc`: 组件数据管理
+- `CategoryBloc`: 分类管理
+- `LikeWidgetBloc`: 收藏功能
+
+### 3. 路由架构
+
+```dart
+GoRoute(
+ path: AppRoute.home.path,
+ routes: [
+ if (kAppEnv.isDesktopUI)
+ ShellRoute(
+ builder: (_, __, Widget child) => AppDeskNavigation(content: child),
+ routes: body,
+ ),
+ if (!kAppEnv.isDesktopUI) ...body,
+ ],
+)
+```
+
+**特点**:
+- 支持桌面端和移动端不同导航
+- 声明式路由配置
+- 深度链接支持
+
+### 4. 数据层架构
+
+#### Repository 模式
+
+```dart
+abstract class WidgetRepository {
+ Future> loadWidgets();
+ Future findWidget(int id);
+ Future> loadNodeByWidgetId(int widgetId);
+}
+```
+
+**实现层**:
+- `WidgetDbRepository`: 数据库实现
+- `MemoryWidgetRepository`: 内存缓存实现
+
+#### 数据库设计
+
+**核心表**:
+- `widget`: Widget基本信息
+- `node`: 示例代码节点
+- `category`: Widget分类
+
+详见: [数据表结构总览](../modules/widget_system/widget_repository/doc/tables_overview.md)
+
+## 平台适配
+
+### 平台检测
+
+```dart
+class kAppEnv {
+ static bool get isWeb;
+ static bool get isDesktopUI;
+ static bool get isMobile;
+}
+```
+
+### 响应式设计
+
+- **移动端**: 底部导航 + 侧滑菜单
+- **桌面端**: 侧边栏导航 + 多窗口布局
+- **Web端**: 响应式布局适配
+
+## 核心功能
+
+### 1. 组件展示系统
+
+- 300+ Flutter组件收录
+- 实时代码演示
+- 交互式组件体验
+- 组件关联跳转
+
+### 2. 搜索与过滤
+
+- 组件名称搜索
+- 星级过滤
+- 分类筛选
+
+### 3. 收藏系统
+
+- 自定义收藏集
+- 收藏集管理
+- 批量操作
+
+### 4. 主题系统
+
+- 明暗主题切换
+- 8种预设颜色主题
+- 6种字体选择
+- 自定义代码高亮
+
+## 性能优化
+
+### 1. 数据缓存
+- 内存缓存: 热点数据常驻内存
+- 数据库缓存: 本地SQLite存储
+
+### 2. 懒加载
+- 路由懒加载: 按需加载页面
+- 组件懒加载: 滚动时动态加载
+
+### 3. 构建优化
+- 代码分割: 模块化打包
+- 资源优化: 图片压缩、字体子集化
+
+## 构建与部署
+
+### 多平台构建
+
+```bash
+# Android
+flutter build apk --target-platform --split-per-abi
+
+# iOS
+flutter build ios
+
+# Web
+flutter build web
+
+# Desktop
+flutter build windows
+flutter build macos
+flutter build linux
+```
+
+### 发布渠道
+
+- Android: APK 直接下载
+- iOS: App Store
+- Web: 在线访问
+- Desktop: 可执行文件下载
+
+## 开发规范
+
+### 代码规范
+- 遵循 Dart 官方代码规范
+- 使用 `flutter_lints` 进行代码检查
+
+### 模块规范
+- 每个模块独立的 `pubspec.yaml`
+- 清晰的模块边界和依赖关系
+
+### 测试规范
+- 单元测试覆盖核心业务逻辑
+- Widget测试验证UI行为
\ No newline at end of file
diff --git a/doc/ewm/coffee1.png b/doc/ewm/coffee1.png
new file mode 100644
index 000000000..dbbf38bc7
Binary files /dev/null and b/doc/ewm/coffee1.png differ
diff --git a/doc/ewm/coffee1.webp b/doc/ewm/coffee1.webp
deleted file mode 100644
index 53ff28e93..000000000
Binary files a/doc/ewm/coffee1.webp and /dev/null differ
diff --git a/doc/screens/preview.webp b/doc/screens/preview.webp
new file mode 100644
index 000000000..79cf8b002
Binary files /dev/null and b/doc/screens/preview.webp differ
diff --git a/doc/version/3.1.0.md b/doc/version/3.1.0.md
new file mode 100644
index 000000000..d551bad2a
--- /dev/null
+++ b/doc/version/3.1.0.md
@@ -0,0 +1,10 @@
+桌面版:
+windows/macos 支持应用内更新,优化更新过程交互
+增加: 知识集锦/布局宝库
+增加 Ctrl+F 全局搜索功能
+
+全端:
+增加收录组件,目前共 354 个
+支持寻路算法演绎
+优化组件详情展示
+支持复制局部代码
diff --git a/doc/version/3.2.0.md b/doc/version/3.2.0.md
new file mode 100644
index 000000000..9afbc2168
--- /dev/null
+++ b/doc/version/3.2.0.md
@@ -0,0 +1,9 @@
+全端:
+增加最新咨询功能
+优化组件列表展示,增加logo设计图
+增加世界留言板
+优化项目结构
+组件数据支持 10 国语言国际化
+
+下载失败,可到下面网站下载最新版
+https://gitee.com/toly1994328/FlutterUnit/releases
\ No newline at end of file
diff --git a/l10n.yaml b/l10n.yaml
new file mode 100644
index 000000000..7312142f3
--- /dev/null
+++ b/l10n.yaml
@@ -0,0 +1,10 @@
+arb-dir: lib/src/l10n/arb
+template-arb-file: app_zh.arb
+output-localization-file: app_l10n.dart
+
+
+synthetic-package: false
+output-dir: lib/src/l10n/gen
+output-class: AppL10n
+nullable-getter: false
+untranslated-messages-file: desiredFileName.txt
\ No newline at end of file
diff --git a/lib/app/bloc_wrapper.dart b/lib/app/bloc_wrapper.dart
deleted file mode 100644
index e81f72b78..000000000
--- a/lib/app/bloc_wrapper.dart
+++ /dev/null
@@ -1,59 +0,0 @@
-import 'package:app/app.dart';
-import 'package:app_update/app_update.dart';
-import 'package:authentication/authentication.dart';
-import 'package:storage/storage.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:flutter_unit/painter_system/bloc/gallery_unit/bloc.dart';
-import 'package:widget_module/blocs/blocs.dart';
-import 'package:widget_repository/widget_repository.dart';
-
-
-
-/// create by 张风捷特烈 on 2020/4/28
-/// contact me by email 1981462002@qq.com
-/// 说明: Bloc提供器包裹层
-
-// final AppStart storage = AppStart();
-
-class BlocWrapper extends StatefulWidget {
- final Widget child;
-
- const BlocWrapper({Key? key, required this.child}) : super(key: key);
-
- @override
- _BlocWrapperState createState() => _BlocWrapperState();
-}
-
-class _BlocWrapperState extends State {
- final WidgetRepository repository = const WidgetDbRepository();
-
- final CategoryBloc categoryBloc= CategoryBloc(repository: CategoryDbRepository());
- final AuthRepository authRepository = HttpAuthRepository();
-
- @override
- Widget build(BuildContext context) {
- return MultiBlocProvider(
- providers: [
- // 全局 bloc : 维护应用存储状态、更新、认证
- BlocProvider(create: (_) => AuthBloc(repository: authRepository)..add(const AppStarted())),
- BlocProvider(create: (_) => AppBloc(AppStateRepository())..initApp()),
- BlocProvider(create: (_) => UpdateBloc()),
- BlocProvider(create: (_) => UserBloc()),
-
-
- BlocProvider(create: (_) => WidgetsBloc(repository: repository)),
- BlocProvider(create: (_) => categoryBloc),
- BlocProvider(create: (_) => LikeWidgetBloc(repository: repository)),
- BlocProvider(create: (_) => CategoryWidgetBloc(categoryBloc: categoryBloc)),
- BlocProvider(create: (_) => GalleryUnitBloc()..loadGalleryInfo()),
- ], child: widget.child);
- }
-
- @override
- void dispose() {
- categoryBloc.close();
- FlutterDbStorage.instance.closeDb();
- super.dispose();
- }
-}
diff --git a/lib/app/flutter_unit.dart b/lib/app/flutter_unit.dart
deleted file mode 100644
index 0d0b54e75..000000000
--- a/lib/app/flutter_unit.dart
+++ /dev/null
@@ -1,48 +0,0 @@
-import 'package:algorithm/algorithm.dart';
-import 'package:app/app.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:flutter_localizations/flutter_localizations.dart';
-
-import 'package:flutter_unit/app/router/unit_router.dart';
-import 'package:flutter_unit/app/views/splash/standard_unit_splash.dart';
-
-/// create by 张风捷特烈 on 2020/4/28
-/// contact me by email 1981462002@qq.com
-/// 说明: 主程序
-
-class FlutterUnit extends StatelessWidget {
- const FlutterUnit({Key? key}) : super(key: key);
-
- @override
- Widget build(BuildContext context) {
- return BlocBuilder(builder: (_, state) {
- return SortStateScope(
- notifier: SortState(),
- child: DefaultTextStyle(
- style: TextStyle(fontFamily: state.fontFamily),
- child: MaterialApp(
- // routes: ,
- showPerformanceOverlay: state.showPerformanceOverlay,
- title: StrUnit.appName,
- debugShowCheckedModeBanner: false,
- onGenerateRoute: UnitRouters.generateRoute,
- localizationsDelegates: GlobalMaterialLocalizations.delegates,
- supportedLocales: const [
- Locale('zh', 'CN'),
- ],
- // themeMode: ThemeMode.light,
- themeMode: state.themeMode,
- darkTheme: AppTheme.darkTheme(state),
- theme: AppTheme.lightTheme(state),
- // theme: ThemeData(
- // primarySwatch: state.themeColor,
- // fontFamily: state.fontFamily,
- // ),
- home: const StandardUnitSplash(),
- ),
- ),
- );
- });
- }
-}
diff --git a/lib/app/navigation/desk_ui/theme_model_switch_icon.dart b/lib/app/navigation/desk_ui/theme_model_switch_icon.dart
deleted file mode 100644
index e8237b664..000000000
--- a/lib/app/navigation/desk_ui/theme_model_switch_icon.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-import 'package:app/app.dart';
-import 'package:components/components.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-
-class ThemeModelSwitchIcon extends StatelessWidget {
- const ThemeModelSwitchIcon({Key? key}) : super(key: key);
-
- @override
- Widget build(BuildContext context) {
- ThemeMode model = context.select((bloc)=>bloc.state.themeMode);
- bool isDark = Theme.of(context).brightness == Brightness.dark;
- return MouseRegion(
- cursor: SystemMouseCursors.click,
- child: GestureDetector(
- onTap: (){
- context.read().changeThemeMode(isDark?ThemeMode.light:ThemeMode.dark);
- },
- child: Padding(
- padding: const EdgeInsets.only(bottom: 16, top: 16),
- child: Icon(
- !isDark?TolyIcon.dark:TolyIcon.wb_sunny,
- color: Colors.white,
- ),
- ),
- ),
- );
- }
-}
diff --git a/lib/app/navigation/desk_ui/unit_desk_navigation.dart b/lib/app/navigation/desk_ui/unit_desk_navigation.dart
deleted file mode 100644
index b69975fbd..000000000
--- a/lib/app/navigation/desk_ui/unit_desk_navigation.dart
+++ /dev/null
@@ -1,96 +0,0 @@
-import 'package:algorithm/algorithm.dart';
-import 'package:app/app.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_unit/code_gen/code_gen_page.dart';
-
-import 'package:flutter_unit/painter_system/gallery_unit.dart';
-import 'package:flutter_unit/widget_ui/desk_ui/widget_panel/widget_panel.dart';
-import 'package:flutter_unit/widget_ui/mobile/category_page/collect_page.dart';
-import 'package:flutter_unit/widget_ui/mobile/category_page/home_right_drawer.dart';
-import '../../../point_system/views/desk_ui/desk_point_page.dart';
-import '../home_drawer.dart';
-import 'unit_rail_navigation.dart';
-
-class UnitDeskNavigation extends StatefulWidget {
-
- const UnitDeskNavigation();
-
- @override
- _UnitDeskNavigationState createState() => _UnitDeskNavigationState();
-
-}
-
-class _UnitDeskNavigationState extends State {
- late PageController _controller; //页面控制器,初始0
- int _currentIndex = 0;
-
- @override
- void initState() {
- super.initState();
- _controller = PageController();
-
- // ActionUnit.searchAction.onSearch = () {
- // Navigator.of(context).pushNamed(UnitRouter.search);
- // };
- }
-
- @override
- void dispose() {
- _controller.dispose(); //释放控制器
- super.dispose();
- }
-
- // 构建悬浮按钮工具
- // Widget wrapOverlayTool({required Widget child}) => Builder(
- // builder: (ctx) => OverlayToolWrapper(
- // child: child,
- // ));
-
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- drawer: const HomeDrawer(),
- endDrawer: const HomeRightDrawer(),
- body: Row(
- children: [
- UnitRailNavigation(
- selectedIndex: _currentIndex,
- onItemClick: _onItemClick, itemData: const {
- "组件集录": TolyIcon.icon_layout,
- "收藏集录": TolyIcon.icon_star,
- "绘制集录": Icons.palette,
- "可视排序": Icons.sort,
- "代码生成": TolyIcon.icon_fast,
- "要点集录": TolyIcon.icon_bug,
- },
- ),
- // _buildLeftNav(),
- Expanded(
- child: PageView(
- physics: const NeverScrollableScrollPhysics(),
- //使用PageView实现页面的切换
- controller: _controller,
- children: const [
- DeskWidgetPanel(),
- CollectPageAdapter(),
- GalleryUnit(),
- DeskSortPage(),
- CodeGenPage(),
- DeskPointPage(),
- ],
- ),
- ),
- ],
- ),
- );
- }
-
- void _onItemClick(int value) {
- _currentIndex = value;
- _controller.jumpToPage(_currentIndex);
- setState(() {
-
- });
- }
-}
-
diff --git a/lib/app/navigation/desk_ui/unit_rail_navigation.dart b/lib/app/navigation/desk_ui/unit_rail_navigation.dart
deleted file mode 100644
index c0447677e..000000000
--- a/lib/app/navigation/desk_ui/unit_rail_navigation.dart
+++ /dev/null
@@ -1,306 +0,0 @@
-import 'package:app/app.dart';
-import 'package:components/toly_ui/toly_ui.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_unit/app/navigation/desk_ui/theme_model_switch_icon.dart';
-import 'package:url_launcher/url_launcher.dart';
-
-class UnitRailNavigation extends StatefulWidget {
- final ValueChanged onItemClick;
- final int selectedIndex;
- final Map itemData;
-
- const UnitRailNavigation(
- {Key? key,
- required this.onItemClick,
- required this.selectedIndex,
- required this.itemData})
- : super(key: key);
-
- @override
- State createState() => _UnitRailNavigationState();
-}
-
-class _UnitRailNavigationState extends State
- with TickerProviderStateMixin {
- late List _destinationControllers;
- late List> _destinationAnimations;
-
- List get info => widget.itemData.keys.toList();
-
- List get icons => widget.itemData.values.toList();
-
- @override
- void initState() {
- super.initState();
- _initControllers();
- }
-
- void _initControllers() {
- _destinationControllers =
- List.generate(widget.itemData.length, (int index) {
- return AnimationController(
- duration: kThemeAnimationDuration,
- vsync: this,
- )..addListener(_rebuild);
- });
-
- _destinationAnimations = _destinationControllers
- .map((AnimationController controller) => controller.view)
- .toList();
- _destinationControllers[widget.selectedIndex].value = 1.0;
- }
-
- void _rebuild() {
- setState(() {
- // Rebuilding when any of the controllers tick, i.e. when the items are
- // animating.
- });
- }
-
- @override
- void didUpdateWidget(UnitRailNavigation oldWidget) {
- super.didUpdateWidget(oldWidget);
- // No animated segue if the length of the items list changes.
- if (widget.itemData.length != oldWidget.itemData.length) {
- _resetState();
- return;
- }
-
- if (widget.selectedIndex != oldWidget.selectedIndex) {
- _destinationControllers[oldWidget.selectedIndex].reverse();
- _destinationControllers[widget.selectedIndex].forward();
- return;
- }
- }
-
- void _resetState() {
- _disposeControllers();
- _initControllers();
- }
-
- void _disposeControllers() {
- for (final AnimationController controller in _destinationControllers) {
- controller.dispose();
- }
- }
-
- @override
- Widget build(BuildContext context) {
- Color? divColor = Theme.of(context).dividerTheme.color;
- return DragToMoveAreaNoDouble(
- child: Container(
- padding: const EdgeInsets.only(top: 20),
- alignment: Alignment.topCenter,
- margin: const EdgeInsets.only(right: 1),
- width: 130,
- decoration: BoxDecoration(color: Color(0xff2C3036), boxShadow: [
- BoxShadow(color: divColor!, offset: Offset(1, 0), blurRadius: 2)
- ]),
- child: Column(
- children: [
- Wrap(
- direction: Axis.vertical,
- spacing: 10,
- crossAxisAlignment: WrapCrossAlignment.center,
- children: const [
- CircleImage(
- image: AssetImage('assets/images/icon_head.webp'),
- size: 60,
- ),
- Text(
- '张风捷特烈',
- style: TextStyle(color: Colors.white70),
- )
- ],
- ),
- buildIcons(),
- const Divider(
- color: Colors.white,
- height: 1,
- endIndent: 20,
- ),
-// SizedBox(height: 60,),
- Expanded(
- flex: 5,
- child: Center(
- //const Size(120, 35)
- child: Column(
- mainAxisSize: MainAxisSize.min,
- children: info
- .asMap()
- .keys
- .map((int index) => _UnitRailMenu(
- animation: _destinationControllers[index],
- onTap: () {
- widget.onItemClick.call(index);
- },
- selected: widget.selectedIndex == index,
- width: 130,
- height: 46,
- activeColor: Theme.of(context).primaryColor,
- inactiveColor: Colors.white.withAlpha(33),
- icon: icons[index],
- label: info[index],
- ))
- .toList(),
- )),
- ),
- Expanded(
- child: Container(),
- flex: 1,
- ),
- const Divider(
- indent: 20,
- color: Colors.white,
- height: 1,
- ),
-
- Wrap(
- spacing: 12,
- children: [
- const ThemeModelSwitchIcon(),
- Builder(
- builder: (ctx) => FeedbackWidget(
- onPressed: () => Scaffold.of(ctx).openDrawer(),
- child: const Padding(
- padding: EdgeInsets.only(bottom: 16, top: 16),
- child: Icon(
- Icons.settings,
- color: Colors.white,
- ),
- ),
- ),
- ),
- ],
- ),
- ],
- ),
- ),
- );
- ;
- }
-
- Widget buildIcons() {
- return Padding(
- padding: const EdgeInsets.only(bottom: 16, top: 16),
- child: Wrap(
- spacing: 8,
- children: [
- FeedbackWidget(
- onPressed: () => _launchURL("http://blog.toly1994.com"),
- child: const Icon(
- TolyIcon.icon_item,
- color: Colors.white,
- ),
- ),
- FeedbackWidget(
- onPressed: () =>
- _launchURL("https://github.com/toly1994328/FlutterUnit"),
- child: const Icon(
- TolyIcon.icon_github,
- color: Colors.white,
- ),
- ),
- FeedbackWidget(
- onPressed: () =>
- _launchURL("https://juejin.im/user/5b42c0656fb9a04fe727eb37"),
- child: const Icon(
- TolyIcon.icon_juejin,
- color: Colors.white,
- ),
- ),
- ],
- ),
- );
- }
-
- _launchURL(String url) async {
- if (await canLaunch(url)) {
- await launch(url);
- } else {
- debugPrint('Could not launch $url');
- }
- }
-}
-
-class _UnitRailMenu extends StatefulWidget {
- final VoidCallback onTap;
- final bool selected;
- final Color activeColor;
- final Color inactiveColor;
- final double width;
- final double height;
- final IconData icon;
- final String label;
- final Animation animation;
-
- _UnitRailMenu({
- Key? key,
- required this.onTap,
- required this.selected,
- required this.width,
- required this.activeColor,
- required this.inactiveColor,
- required this.height,
- required this.animation,
- required this.icon,
- required this.label,
- }) : super(key: key);
-
- @override
- State<_UnitRailMenu> createState() => _UnitRailMenuState();
-}
-
-class _UnitRailMenuState extends State<_UnitRailMenu> {
- @override
- Widget build(BuildContext context) {
- return GestureDetector(
- onTap: widget.onTap,
- child: Container(
- alignment: Alignment.topLeft,
- margin: const EdgeInsets.only(top: 10),
- child: AnimatedBuilder(
- animation: widget.animation,
- builder: (BuildContext context, Widget? child) => _buildItem(),
- ),
- ));
- }
-
- late ColorTween colorTween = ColorTween(begin: widget.inactiveColor, end: widget.activeColor);
-
- Widget _buildItem() {
- double iconSize = _sizeTween.transform(widget.animation.value);
- Color? color = colorTween.transform(widget.animation.value);
- return Container(
- alignment: Alignment.center,
- decoration: BoxDecoration(
- color: color,
- borderRadius: BorderRadius.only(
- topRight: Radius.circular(widget.height / 2),
- bottomRight: Radius.circular(widget.height / 2))),
- width: _widthTween.transform(widget.animation.value) * widget.width,
- height: widget.height,
- child: Wrap(
- spacing: 6,
- crossAxisAlignment: WrapCrossAlignment.center,
- children: [
- Icon(
- widget.icon,
- size: iconSize,
- color: widget.selected ? Colors.white : Colors.white70,
- ),
- Text(
- widget.label,
- style: TextStyle(
- fontSize: 14,
- color: widget.selected ? Colors.white : Colors.white70,
- ),
- ),
- ],
- ),
- );
- }
-}
-
-final Tween _widthTween = Tween(begin: 0.82, end: 0.95);
-final Tween _sizeTween = Tween(begin: 18.0, end: 20.0);
diff --git a/lib/app/navigation/pure_bottom_bar.dart b/lib/app/navigation/pure_bottom_bar.dart
deleted file mode 100644
index 71757e3c2..000000000
--- a/lib/app/navigation/pure_bottom_bar.dart
+++ /dev/null
@@ -1,80 +0,0 @@
-import 'package:app/app.dart';
-import 'package:flutter/material.dart';
-
-typedef IndexTapCallback = void Function(int);
-typedef IndexLongTapCallback = void Function(BuildContext, int);
-
-class PureBottomBar extends StatefulWidget {
- final int initPosition;
-
- // item 点击事件
- final IndexTapCallback? onItemTap;
-
- // item 长按事件
- final IndexLongTapCallback? onItemLongTap;
- const PureBottomBar(
- {Key? key, this.onItemTap, this.onItemLongTap, this.initPosition = 0})
- : super(key: key);
-
- @override
- State createState() => _PureBottomBarState();
-}
-
-class _PureBottomBarState extends State {
- List get bottomBar => const ['组件', '绘制',
- '知识',
- '收藏', '我的'];
-
- List get bottomBarIcon => const [
- TolyIcon.icon_layout,
- TolyIcon.dingzhi1,
- TolyIcon.icon_artifact,
- TolyIcon.icon_collect,
- TolyIcon.yonghu,
- ];
- int _position = 0;
-
- @override
- void initState() {
- super.initState();
- _position = widget.initPosition;
- }
-
- @override
- Widget build(BuildContext context) {
- return Wrap(
- children: [
- // Divider(height: 1,),
- BottomNavigationBar(
- // backgroundColor: Colors.white,
- onTap: (position) {
- // checkTokenExpires();
- _position = position;
-
- widget.onItemTap?.call(_position);
- setState(() {
- // _controller.jumpToPage(_position);
- });
- },
- currentIndex: _position,
-
- elevation: 3,
- // fixedColor: themeColor.activeColor,
- type: BottomNavigationBarType.fixed,
- iconSize: 22,
- selectedItemColor: Theme.of(context).primaryColor,
- selectedLabelStyle: const TextStyle(fontWeight: FontWeight.bold),
- showUnselectedLabels: true,
- showSelectedLabels: true,
- // backgroundColor: themeColor.itemColor,
- items: bottomBar
- .asMap()
- .keys
- .map((index) => BottomNavigationBarItem(
- label: bottomBar[index], icon: Icon(bottomBarIcon[index])))
- .toList(),
- ),
- ],
- );
- }
-}
diff --git a/lib/app/navigation/route/route.dart b/lib/app/navigation/route/route.dart
deleted file mode 100644
index 70f18eb0a..000000000
--- a/lib/app/navigation/route/route.dart
+++ /dev/null
@@ -1,41 +0,0 @@
-import 'dart:io';
-
-import 'package:app/app.dart';
-import 'package:flutter/material.dart';
-
-import '../../views/setting/code_style_setting.dart';
-import '../../views/setting/font_setting.dart';
-import '../../views/setting/setting_page.dart';
-import '../../views/setting/theme_color_setting.dart';
-import '../unit_navigation.dart';
-
-class RoutePath {
-
- static const String nav = 'nav';
-
- static const String themeColorSetting = 'ThemeColorSettingPage';
- static const String codeStyleSetting = 'CodeStyleSettingPage';
- static const String itemStyleSetting = 'ItemStyleSettingPage';
- static const String fontSetting = 'FountSettingPage';
-
- Map get routes =>
- {
- themeColorSetting: (ctx) => const ThemeColorSettingPage(),
- codeStyleSetting: (ctx) => const CodeStyleSettingPage(),
- fontSetting: (ctx) => const FontSettingPage(),
- };
-
-
- static Route? generateRoute(RouteSettings settings) {
- switch (settings.name) {
- case nav:
- if (Platform.isWindows || Platform.isMacOS || Platform.isLinux) {
- return ZeroPageRoute(child: UnitNavigation());
- }
- return SlidePageRoute(child: UnitNavigation());
- }
-
- return null;
- }
-
-}
\ No newline at end of file
diff --git a/lib/app/navigation/unit_drawer_header.dart b/lib/app/navigation/unit_drawer_header.dart
deleted file mode 100644
index 0d5572925..000000000
--- a/lib/app/navigation/unit_drawer_header.dart
+++ /dev/null
@@ -1,87 +0,0 @@
-import 'package:flutter/material.dart';
-
-/// create by 张风捷特烈 on 2020-04-22
-/// contact me by email 1981462002@qq.com
-/// 说明:
-
-class UnitDrawerHeader extends StatelessWidget {
- final Color color;
-
-
- const UnitDrawerHeader({Key? key, required this.color}) : super(key: key);
-
- @override
- Widget build(BuildContext context) {
- return DrawerHeader(
- padding: const EdgeInsets.only(top: 10, left: 15),
- decoration: const BoxDecoration(
- image: DecorationImage(
- image: AssetImage('assets/images/wy_300x200_filter.webp'),
- fit: BoxFit.cover),
- ),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Wrap(
- spacing: 10,
- crossAxisAlignment: WrapCrossAlignment.center,
- children: const [
- FlutterLogo(
- size: 35,
- ),
- Text(
- 'Flutter Unit',
- style: TextStyle(fontSize: 24, color: Colors.white, shadows: [
- Shadow(
- color: Colors.black,
- offset: Offset(1, 1),
- blurRadius: 3)
- ]),
- ),
- ],
- ),
- const SizedBox(
- height: 15,
- ),
- Text(
- 'The Unity Of Flutter, The Unity Of Coder.',
- style: TextStyle(fontSize: 15, color: Colors.white, shadows: [
- Shadow(color: color, offset: const Offset(.5, .5), blurRadius: 1)
- ]),
- ),
- const SizedBox(
- height: 5,
- ),
- Text(
- 'Flutter的联合,编程者的联合。',
- style: TextStyle(fontSize: 15, color: Colors.white, shadows: [
- Shadow(color: color, offset: const Offset(.5, .5), blurRadius: 1)
- ]),
- ),
- const SizedBox(
- height: 10,
- ),
- Row(
- children: const [
- Spacer(
- flex: 5,
- ),
- Text(
- '—— 张风捷特烈',
- style: TextStyle(fontSize: 15, color: Colors.white, shadows: [
- Shadow(
- color: Colors.orangeAccent,
- offset: Offset(.5, .5),
- blurRadius: 1)
- ]),
- ),
- Spacer(
- flex: 1,
- ),
- ],
- ),
- ],
- ),
- );
- }
-}
diff --git a/lib/app/navigation/unit_navigation.dart b/lib/app/navigation/unit_navigation.dart
deleted file mode 100644
index b0dd3b762..000000000
--- a/lib/app/navigation/unit_navigation.dart
+++ /dev/null
@@ -1,133 +0,0 @@
-import 'dart:io';
-
-import 'package:app/app.dart';
-import 'package:app_update/app_update.dart';
-import 'package:artifact/artifact.dart';
-import 'package:authentication/authentication.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:flutter_unit/painter_system/gallery_unit.dart';
-import 'package:flutter_unit/widget_ui/mobile/category_page/collect_page.dart';
-import 'package:flutter_unit/widget_ui/mobile/category_page/home_right_drawer.dart';
-import 'package:widget_module/blocs/blocs.dart';
-import 'package:flutter_unit/widget_ui/mobile/widget_panel/standard_home_page.dart';
-
-
-import 'pure_bottom_bar.dart';
-import 'desk_ui/unit_desk_navigation.dart';
-
-/// create by 张风捷特烈 on 2020-04-11
-/// contact me by email 1981462002@qq.com
-/// 说明: 主题结构 左右滑页 + 底部导航栏
-
-class UnitNavigation extends StatelessWidget {
- const UnitNavigation({Key? key}) : super(key: key);
-
- @override
- Widget build(BuildContext context) {
- return BlocBuilder(
- builder: (_, state) => LayoutBuilder(builder: (_, c) {
- if (c.maxWidth > 500) {
- return UnitDeskNavigation();
- }
- return UnitPhoneNavigation();
- }),
- );
- }
-}
-
-class UnitPhoneNavigation extends StatefulWidget {
- const UnitPhoneNavigation({Key? key}) : super(key: key);
-
- @override
- _UnitPhoneNavigationState createState() => _UnitPhoneNavigationState();
-}
-
-class _UnitPhoneNavigationState extends State {
- //页面控制器,初始 0
- final PageController _controller = PageController();
- int position = 0;
-
- // 禁止 PageView 滑动
- final ScrollPhysics _neverScroll = const NeverScrollableScrollPhysics();
-
- @override
- void initState() {
- super.initState();
- if (Platform.isAndroid||Platform.isIOS) {
- BlocProvider.of(context).add(const CheckUpdate(appName: 'FlutterUnit'));
- }
- }
-
- @override
- void dispose() {
- _controller.dispose(); //释放控制器
- super.dispose();
- }
-
- /// extendBody = true 凹嵌透明,需要处理底部 边距
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- extendBody: true,
- endDrawer: const HomeRightDrawer(),
- body: PageView(
- physics: _neverScroll,
- controller: _controller,
- children: [
- StandardHomePage(),
- GalleryUnit(),
- ArtifactPage(),
- CollectPageAdapter(),
- UserPage(),
- ],
- ),
- bottomNavigationBar: _buildBottomNav(context),
- );
- }
-
- bool get isDark => Theme.of(context).brightness == Brightness.dark;
-
-
- // 由于 bottomNavigationBar 颜色需要随 点击头部栏 状态而改变,
- // 使用 BlocBuilder 构建
- Widget _buildBottomNav(BuildContext context) {
- return Stack(
- children: [
- PureBottomBar(
- initPosition: position,
- onItemTap: _onTapBottomNav,
- onItemLongTap: _onItemLongTap,
- ),
- const Positioned(right: 26, top: 8, child: UpdateRedPoint())
- ],
- );
- }
-
- // 点击底部按钮事件,切换页面
- void _onTapBottomNav(int index) {
- _controller.jumpToPage(index);
- position = index;
- if (!isDark) {
- late Color color;
- if (index != 0) {
- color = Theme.of(context).primaryColor;
- } else {
- }
- }
-
- if (index == 3) {
- BlocProvider.of(context).add(const EventLoadLikeData());
- }
- }
-
- // 两侧
- void _onItemLongTap(BuildContext context, int index) {
- if (index == 0) {
- Scaffold.of(context).openDrawer();
- }
- if (index == 4) {
- Scaffold.of(context).openEndDrawer();
- }
- }
-}
diff --git a/lib/app/router/desk/app.dart b/lib/app/router/desk/app.dart
deleted file mode 100644
index d590176ab..000000000
--- a/lib/app/router/desk/app.dart
+++ /dev/null
@@ -1,49 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:go_router/go_router.dart';
-
-import '../menu_meta.dart';
-
-
-final List deskNavBarMenus = const [
- MenuMeta(label: '组件集录', icon: Icons.color_lens_outlined, path: '/widgets'),
- MenuMeta(label: '收藏集录', icon: Icons.add_chart, path: '/collection'),
- MenuMeta(label: '绘制集录', icon: Icons.sort, path: '/painter'),
- MenuMeta(label: '可视化', icon: Icons.person, path: '/visual'),
- MenuMeta(label: '代码生成', icon: Icons.settings, path: '/code_gen'),
- MenuMeta(label: '要点集录', icon: Icons.settings, path: '/pointer'),
-];
-
-
-// final RouteBase appRoute = ShellRoute(
-// builder: (BuildContext context, GoRouterState state, Widget child) {
-// return AppNavigation(navigator: child);
-// },
-// routes: [
-// colorRouters,
-// GoRoute(
-// path: 'counter',
-// builder: (BuildContext context, GoRouterState state) {
-// return const CounterPage();
-// }),
-// sortRouters,
-// GoRoute(
-// path: 'user',
-// builder: (BuildContext context, GoRouterState state) {
-// return const UserPage();
-// },
-// ),
-// GoRoute(
-// path: 'settings',
-// builder: (BuildContext context, GoRouterState state) {
-// return const SettingPage();
-// },
-// ),
-// GoRoute(
-// path: '404',
-// builder: (BuildContext context, GoRouterState state) {
-// String msg = '无法访问: ${state.extra}';
-// return EmptyPanel(msg: msg);
-// },
-// )
-// ],
-// );
diff --git a/lib/app/router/desk/root.dart b/lib/app/router/desk/root.dart
deleted file mode 100644
index 4fe06a313..000000000
--- a/lib/app/router/desk/root.dart
+++ /dev/null
@@ -1,34 +0,0 @@
-import 'dart:async';
-
-import 'package:flutter/material.dart';
-import 'package:go_router/go_router.dart';
-
-import '../../views/splash/standard_unit_splash.dart';
-import 'app.dart';
-
-final RouteBase rootRoute = GoRoute(
- path: '/',
- redirect: _redirect,
- routes: [
- // appRoute,
- // GoRoute(
- // path: 'login',
- // builder: (BuildContext context, GoRouterState state) {
- // return const LoginPage();
- // },
- // ),
- GoRoute(
- path: 'splash',
- builder: (BuildContext context, GoRouterState state) {
- return const StandardUnitSplash();
- },
- ),
- ],
-);
-
-FutureOr _redirect(BuildContext context, GoRouterState state) {
- if(state.fullPath=='/'){
- return '/splash';
- }
- return null;
-}
diff --git a/lib/app/router/menu_meta.dart b/lib/app/router/menu_meta.dart
deleted file mode 100644
index 34032961f..000000000
--- a/lib/app/router/menu_meta.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-import 'package:flutter/material.dart';
-
-class MenuMeta {
- // 标签
- final String label;
-
- final String? path;
-
- // 图标数据
- final IconData icon;
-
- // 图标颜色
- final Color? color;
-
- const MenuMeta({
- required this.label,
- this.path,
- required this.icon,
- this.color,
- });
-}
diff --git a/lib/app/router/unit_router.dart b/lib/app/router/unit_router.dart
deleted file mode 100644
index 687a8dfeb..000000000
--- a/lib/app/router/unit_router.dart
+++ /dev/null
@@ -1,148 +0,0 @@
-// ignore_for_file: constant_identifier_names
-
-import 'dart:io';
-
-import 'package:app/app.dart';
-import 'package:authentication/authentication.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_unit/app/navigation/unit_navigation.dart';
-import 'package:flutter_unit/app/views/about/about_app_page.dart';
-import 'package:flutter_unit/app/views/about/about_me_page.dart';
-import 'package:flutter_unit/app/views/about/version_info.dart';
-import 'package:flutter_unit/app/views/data_manage/data_manage_page.dart';
-import 'package:flutter_unit/app/views/setting/code_style_setting.dart';
-import 'package:flutter_unit/app/views/setting/font_setting.dart';
-import 'package:flutter_unit/app/views/setting/item_style_setting.dart';
-import 'package:flutter_unit/app/views/setting/setting_page.dart';
-import 'package:flutter_unit/app/views/setting/theme_color_setting.dart';
-import 'package:flutter_unit/app/views/unit_todo/attr_unit_page.dart';
-import 'package:flutter_unit/app/views/unit_todo/layout_unit_page.dart';
-import 'package:flutter_unit/app/views/unit_todo/point_unit_page.dart';
-import 'package:flutter_unit/point_system/views/issues_point/issues_detail.dart';
-import 'package:flutter_unit/point_system/views/issues_point/issues_point_page.dart';
-import 'package:flutter_unit/widget_ui/desk_ui/widget_detail/widget_detail_page.dart';
-import 'package:flutter_unit/widget_ui/mobile/category_page/category_detail.dart';
-import 'package:flutter_unit/widget_ui/mobile/category_page/collect_page.dart';
-import 'package:flutter_unit/widget_ui/mobile/search_page/search_page.dart';
-import 'package:flutter_unit/widget_ui/mobile/widget_detail/widget_detail_page.dart';
-import 'package:widget_repository/widget_repository.dart';
-
-
-class UnitRouters {
- static const String widget_detail = '/widget_detail';
-
- static const String detail = 'detail';
- // static const String search = 'search_bloc';
-
-
- static const String collect = 'CollectPage';
- static const String point = 'IssuesPointPage';
- static const String point_detail = 'IssuesDetailPage';
-
- static const String setting = 'SettingPage';
- static const String font_setting = 'FountSettingPage';
- static const String theme_color_setting = 'ThemeColorSettingPage';
- static const String code_style_setting = 'CodeStyleSettingPage';
- static const String item_style_setting = 'ItemStyleSettingPage';
- static const String version_info = 'VersionInfo';
- static const String login = 'login';
-
- static const String category_show = 'CategoryShow';
- static const String issues_point = 'IssuesPointPage';
-
- static const String attr = 'AttrUnitPage';
- static const String bug = 'BugUnitPage';
- static const String layout = 'LayoutUnitPage';
- static const String about_me = 'AboutMePage';
- static const String about_app = 'AboutAppPage';
- static const String register = 'register';
-
- static const String data_manage = 'DataManagePage';
-
- static Route generateRoute(RouteSettings settings) {
- switch (settings.name) {
- //
- case UnitRouter.nav:
- if(Platform.isWindows||Platform.isMacOS||Platform.isLinux){
- return ZeroPageRoute( child: UnitNavigation());
- }
- return SlidePageRoute(child: UnitNavigation());
-
- // 组件详情页
- case widget_detail:
- Widget child;
- if(Platform.isWindows||Platform.isMacOS||Platform.isLinux){
- child = DeskWidgetDetailPageScope(
- model: settings.arguments as WidgetModel,
- );
- }else{
- child = WidgetDetailPageScope(
- model: settings.arguments as WidgetModel,
- );
- }
-
- return SlidePageRoute(child: child);
-
- // case search:
- // return Right2LeftRouter(child: const SearchPageProvider());
- case collect:
- return SlidePageRoute(child: CollectPageAdapter(
- canPop: settings.arguments as bool,
- ));
-
- case setting:
- return SlidePageRoute(child: const SettingPage());
- // return Right2LeftRouter(builder:(_)=> const SettingPage());
- // return MaterialPageRoute(builder:(_)=> const SettingPage());
- case data_manage:
- return SlidePageRoute(child: const DataManagePage());
- case font_setting:
- return SlidePageRoute(child: const FontSettingPage());
- case theme_color_setting:
- return SlidePageRoute(child: const ThemeColorSettingPage());
- case code_style_setting:
- return SlidePageRoute(child: const CodeStyleSettingPage());
- // case item_style_setting:
- // return Right2LeftRouter(child: const ItemStyleSettingPage());
-
- case version_info:
- return SlidePageRoute(child: const VersionInfo());
-
- case issues_point:
- return SlidePageRoute(child: const IssuesPointScope());
- case login:
- return SlidePageRoute(child: const LoginPage());
-
- case register:
- return SlidePageRoute(child: const RegisterPage());
-
- case attr:
- return SlidePageRoute(child: const AttrUnitPage());
- case bug:
- return SlidePageRoute(child: const BugUnitPage());
- case layout:
- return SlidePageRoute(child: const LayoutUnitPage());
- case about_app:
- return SlidePageRoute(child: const AboutAppPage());
- case about_me:
- return SlidePageRoute(child: const AboutMePage());
-
- case point_detail:
- return SlidePageRoute(child: const IssuesDetailPage());
-
- case category_show:
- return SlidePageRoute(
- child: CategoryShow(
- model: settings.arguments as CategoryModel,
- ));
-
- default:
- return MaterialPageRoute(
- builder: (_) => Scaffold(
- body: Center(
- child: Text('No route defined for ${settings.name}'),
- ),
- ));
- }
- }
-}
diff --git a/lib/app/utils/Toast.dart b/lib/app/utils/Toast.dart
deleted file mode 100644
index 2f174108e..000000000
--- a/lib/app/utils/Toast.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-// import 'package:flutter/material.dart';
-//
-// class Toast {
-// static toast(BuildContext context, String msg,
-// {duration = const Duration(milliseconds: 600),
-// Color? color,
-// SnackBarAction? action}) {
-//
-// ScaffoldMessenger.of(context).showSnackBar(SnackBar(
-// content: Text(msg),
-// duration: duration,
-// action: action,
-// backgroundColor: color??Theme.of(context).primaryColor,
-// ));
-// }
-//
-// static void error(BuildContext context,String msg){
-// toast(context,msg, color:Colors.red, );
-// }
-//
-// static void warning(BuildContext context,String msg){
-// toast(context,msg, color:Colors.orange, );
-// }
-//
-// static void success(BuildContext context,String msg){
-// toast(context,msg, color:Theme.of(context).primaryColor, );
-// }
-//
-// static void green(BuildContext context,String msg){
-// toast(context,msg, color:Colors.green, );
-// }
-// }
diff --git a/lib/app/utils/color_utils.dart b/lib/app/utils/color_utils.dart
deleted file mode 100644
index 75170c730..000000000
--- a/lib/app/utils/color_utils.dart
+++ /dev/null
@@ -1,73 +0,0 @@
-import 'dart:math';
-
-import 'package:flutter/material.dart';
-
-import 'random_provider.dart';
-
-
-
-class ColorUtils {
- static Color randomColor({
- int limitA = 120,
- int limitR = 0,
- int limitG = 0,
- int limitB = 0,
- }) {
- Random random = RandomProvider.random;
- int a = limitA + random.nextInt(256 - limitA); //透明度值
- int r = limitR + random.nextInt(256 - limitR); //红值
- int g = limitG + random.nextInt(256 - limitG); //绿值
- int b = limitB + random.nextInt(256 - limitB); //蓝值
- return Color.fromARGB(a, r, g, b); //生成argb模式的颜色
- }
-
-
- /// 使用方法:
- /// var color1=ColorUtils.parse("#33428A43");
- /// var color2=ColorUtils.parse("33428A43");
- /// var color3=ColorUtils.parse("#428A43");
- ///var color4=ColorUtils.parse("428A43");
- ///
- static Color parse(String code) {
- Color result =Colors.red;
- int value = 0 ;
- if (code.contains("#")) {
- try {
- value = int.parse(code.substring(1), radix: 16);
- } catch (e) {
- print(e);
- }
- switch (code.length) {
- case 7://6位
- result = Color(value + 0xFF000000);
- break;
- case 9://8位
- result = Color(value);
- break;
- default:
- result =Colors.red;
- }
- }else {
- try {
- value = int.parse(code, radix: 16);
- } catch (e) {
- print(e);
- }
- switch (code.length) {
- case 6:
- result = Color(value + 0xFF000000);
- break;
- case 8:
- result = Color(value);
- break;
- default:
- result =Colors.red;
- }
- }
- return result;
- }
-
- static String colorString(Color color) =>
- "#${color.value.toRadixString(16).padLeft(8, '0').toUpperCase()}";
-}
-
diff --git a/lib/app/utils/convert.dart b/lib/app/utils/convert.dart
deleted file mode 100644
index 9c3c2ec99..000000000
--- a/lib/app/utils/convert.dart
+++ /dev/null
@@ -1,51 +0,0 @@
-
-import 'package:flutter_unit/painter_system/gallery_factory.dart';
-import 'package:widget_repository/widget_repository.dart';
-
-/// create by 张风捷特烈 on 2020-03-07
-/// contact me by email 1981462002@qq.com
-/// 说明:
-
-class Convert {
- static WidgetFamily toFamily(int id) {
- switch (id) {
- case 0:
- return WidgetFamily.statelessWidget;
- case 1:
- return WidgetFamily.statefulWidget;
- case 2:
- return WidgetFamily.singleChildRenderObjectWidget;
- case 3:
- return WidgetFamily.multiChildRenderObjectWidget;
- case 4:
- return WidgetFamily.sliver;
- case 5:
- return WidgetFamily.proxyWidget;
- case 6:
- return WidgetFamily.other;
- default:
- return WidgetFamily.statelessWidget;
- }
- }
-
- static Map galleryTypeMap = {
- GalleryType.base: "基础绘制",
- GalleryType.fun: "趣味绘制",
- GalleryType.particle: "粒子绘制",
- GalleryType.anim: "动画手势",
- GalleryType.art: "艺术画廊",
- };
-
- static String convertFileSize(int size){
- double result = size / 1024.0;
- if(result<1024){
- return "${result.toStringAsFixed(2)} Kb";
- }else if(result>1024&&result<1024*1024){
- return "${(result/1024).toStringAsFixed(2)} Mb";
- }else{
- return "${(result/1024/1024).toStringAsFixed(2)} Gb";
- }
- }
-
-
-}
diff --git a/lib/app/utils/pather.dart b/lib/app/utils/pather.dart
deleted file mode 100644
index 6953fdf34..000000000
--- a/lib/app/utils/pather.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-import 'dart:math';
-
-import 'package:flutter/cupertino.dart';
-
-class Pather {
- Pather._();
-
- static Pather create = Pather._();
-
- final Path _path = Path();
-
- Path nStarPath(int num, double R, double r, {dx = 0, dy = 0}) {
- _path.reset();//重置路径
- double perRad = 2 * pi / num;//每份的角度
- double radA = perRad / 2 / 2;//a角
- double radB = 2 * pi / (num - 1) / 2 - radA / 2 + radA;//起始b角
- _path.moveTo(cos(radA) * R + dx, -sin(radA) * R + dy);//移动到起点
- for (int i = 0; i < num; i++) {//循环生成点,路径连至
- _path.lineTo(cos(radA + perRad * i) * R + dx, -sin(radA + perRad * i) * R + dy);
- _path.lineTo(cos(radB + perRad * i) * r + dx, -sin(radB + perRad * i) * r + dy);
- }
- _path.close();
- return _path;
- }
-}
diff --git a/lib/app/utils/toly_utils.dart b/lib/app/utils/toly_utils.dart
deleted file mode 100644
index ea48a992e..000000000
--- a/lib/app/utils/toly_utils.dart
+++ /dev/null
@@ -1,3 +0,0 @@
-library toly_utils;
-export 'color_utils.dart';
-export 'random_provider.dart';
diff --git a/lib/app/views/about/version/version_shower.dart b/lib/app/views/about/version/version_shower.dart
deleted file mode 100644
index 3c20a2cd9..000000000
--- a/lib/app/views/about/version/version_shower.dart
+++ /dev/null
@@ -1,33 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:package_info_plus/package_info_plus.dart';
-
-class VersionShower extends StatefulWidget {
- const VersionShower({Key? key}) : super(key: key);
-
- @override
- _VersionShowerState createState() => _VersionShowerState();
-}
-
-class _VersionShowerState extends State {
- String version = '1.0.0';
-
- @override
- void initState() {
- super.initState();
- _fetchVersion();
- }
-
- @override
- Widget build(BuildContext context) {
- return Text('Version $version');
- }
-
- void _fetchVersion() async{
- PackageInfo packageInfo = await PackageInfo.fromPlatform();
- if(mounted) {
- setState(() {
- version= packageInfo.version;
- });
- }
- }
-}
diff --git a/lib/app/views/data_manage/data_manage_page.dart b/lib/app/views/data_manage/data_manage_page.dart
deleted file mode 100644
index 51bca2ca9..000000000
--- a/lib/app/views/data_manage/data_manage_page.dart
+++ /dev/null
@@ -1,147 +0,0 @@
-import 'dart:convert';
-import 'dart:io';
-import 'package:app/app.dart';
-import 'package:storage/storage.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/services.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-
-import 'package:flutter_unit/point_system/api/category_api.dart';
-
-import 'package:authentication/views/authentic_widget.dart';
-import 'package:utils/utils.dart';
-import 'package:widget_module/blocs/blocs.dart';
-
-import 'package:path/path.dart' as path;
-import 'package:sqflite/sqflite.dart';
-import 'package:widget_repository/widget_repository.dart';
-
-/// create by 张风捷特烈 on 2021/2/26
-/// contact me by email 1981462002@qq.com
-/// 说明:
-///
-
-class DataManagePage extends StatelessWidget {
- const DataManagePage({Key? key}) : super(key: key);
-
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: const Text('数据管理'),
- ),
- body: Builder(
- builder: (ctx) => ListView(
- children: [
- AuthenticWidget.just(
- ListTile(
- trailing: Icon(
- TolyIcon.upload,
- color: Theme.of(context).primaryColor,
- ),
- title: const Text('备份收藏集数据'),
- onTap: () => _doUploadCategoryData(ctx),
- ),
- ),
- AuthenticWidget.just(const Divider()),
- AuthenticWidget.just(ListTile(
- trailing: Icon(
- TolyIcon.download,
- color: Theme.of(context).primaryColor,
- ),
- title: const Text('同步收藏集数据'),
- onTap: () => _doSync(ctx),
- )),
- AuthenticWidget.just(const Divider()),
- ListTile(
- trailing: Icon(
- Icons.refresh,
- color: Theme.of(context).primaryColor,
- ),
- title: const Text('收藏集数据重置'),
- // trailing: _nextIcon(context),
- onTap: () => _recallDatabase(ctx),
- ),
- const Divider(),
- ],
- ),
- ),
- );
- }
-
- _recallDatabase(BuildContext context) async {
- String databasesPath = await getDatabasesPath();
- String dbPath = path.join(databasesPath, "flutter.db");
- ByteData data = await rootBundle.load(path.join("assets", "flutter.db"));
- List bytes =
- data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
- await File(dbPath).writeAsBytes(bytes, flush: true);
- print("==== debug ===== assets ======拷贝完成====");
- BlocProvider.of(context).add(const EventLoadCategory());
- BlocProvider.of(context).add(const EventLoadLikeData());
- Toast.toast(context, '重置成功!');
- }
-
- void _doUploadCategoryData(BuildContext context) async {
- CategoryRepository rep = BlocProvider.of(context).repository;
- List loadCategories = await rep.loadCategoryData();
-
- List likeData = await FlutterDbStorage.instance.likeDao.likeWidgetIds();
-
- String json = jsonEncode(loadCategories);
- String likeJson = jsonEncode(likeData);
-
- TaskResult result =
- await CategoryApi.uploadCategoryData(data: json, likeData: likeJson);
-
- if (result.success) {
- Toast.toast(context, '数据集备份成功!');
- } else {
- Toast.toast(context, '数据集备份失败!');
- }
- }
-
- void _doSync(BuildContext context) async {
- TaskResult result = await CategoryApi.getCategoryData();
-
- if (result.success) {
- // 说明请求成功
- if (result.data != null) {
- //说明有后台备份数据,进行同步操作
- CategoryRepository repository =
- BlocProvider.of(context).repository;
- await repository.syncCategoryByData(
- result.data!.data, result.data!.likeData);
- BlocProvider.of(context).add(const EventLoadCategory());
- BlocProvider.of(context).add(const EventLoadLikeData());
- } else {
- // 说明还没有后台数据,
- // 这里防止有傻孩子没点备份,就点同步,哥哥好心,给备份一下。
- CategoryRepository rep =
- BlocProvider.of(context).repository;
- List loadCategories = await rep.loadCategoryData();
- List likeData = await FlutterDbStorage.instance.likeDao.likeWidgetIds();
-
- String json = jsonEncode(loadCategories);
- String likeJson = jsonEncode(likeData);
- await CategoryApi.uploadCategoryData(data: json, likeData: likeJson);
- }
- Toast.toast(context, '数据同步份成功!');
- } else {
- Toast.toast(context, '数据同步份失败!');
- }
- }
-}
-
-// class LoadingIndicate extends StatefulWidget {
-// Future Function task;
-// @override
-// _LoadingIndicateState createState() => _LoadingIndicateState();
-// }
-//
-// class _LoadingIndicateState extends State {
-// @override
-// Widget build(BuildContext context) {
-// return Container();
-// }
-// }
diff --git a/lib/app/views/setting/setting_page.dart b/lib/app/views/setting/setting_page.dart
deleted file mode 100644
index efc22e206..000000000
--- a/lib/app/views/setting/setting_page.dart
+++ /dev/null
@@ -1,168 +0,0 @@
-import 'package:app/app.dart';
-import 'package:components/components.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:flutter_unit/app/navigation/overlay_tool_wrapper.dart';
-
-
-import 'app_style_setting.dart';
-import 'theme_model_setting.dart';
-
-class SettingPage extends StatelessWidget {
-
- const SettingPage({Key? key}) : super(key: key);
-
- @override
- Widget build(BuildContext context) {
- const Widget divider = Divider(height: 1);
-
- return Scaffold(
- appBar: AppBar(title:Text('应用设置')),
- body: ListView(
- children: [
- Container( height: 15),
- ListTile(
- leading: Icon(
- Icons.style,
- color: Theme.of(context).primaryColor,
- ),
- title: const Text('深色模式', style: TextStyle(fontSize: 16)),
- subtitle: BlocBuilder(
- builder: (_,state)=>Text(
- themeMode2Str[state.themeMode]!
- , style: const TextStyle(fontSize: 12,color: Colors.grey)
- ),
- ),
- trailing: _nextIcon(context),
- onTap: (){
- Navigator.of(context).push(SlidePageRoute(child: ThemeModelSetting()));
- },
- ),
- divider,
- ListTile(
- leading: Icon(
- Icons.palette,
- color: Theme.of(context).primaryColor,
- ),
- title: const Text('主题色设置', style: TextStyle(fontSize: 16)),
- subtitle: BlocBuilder(
- builder: (_,state)=>Text(
- Cons.kThemeColorSupport[state.themeColor]!,
- style: TextStyle(color: state.themeColor,fontSize: 12),
- ),
- ),
- trailing: _nextIcon(context),
- onTap: () => Navigator.of(context).pushNamed(UnitRouter.theme_color_setting),
- ),
- // divider,
- Container( height: 10),
- ListTile(
- leading: Icon(
- Icons.translate,
- color: Theme.of(context).primaryColor,
- ),
- title: const Text('字体设置', style: TextStyle(fontSize: 16)),
- subtitle: BlocBuilder(
- builder: (_,state)=>Text(
- state.fontFamily,style: TextStyle(fontSize: 12),
- ),
- ),
- trailing: _nextIcon(context),
- onTap: () => Navigator.of(context).pushNamed(UnitRouter.font_setting),
- ),
- divider,
- ListTile(
- leading: Icon(
- TolyIcon.icon_code,
- color: Theme.of(context).primaryColor,
- ),
- title: const Text('代码高亮样式', style: TextStyle(fontSize: 16)),
- trailing: _nextIcon(context),
- onTap: () => Navigator.of(context).pushNamed(UnitRouter.code_style_setting),
- ),
- // divider,
- Container( height: 10,),
- _buildShowBg(context),
- divider,
- _buildShowOver(context),
- // divider,
- // _buildShowTool(context),
- // divider,
- Container( height: 10),
- ListTile(
- leading: Icon(
- Icons.info,
- color: Theme.of(context).primaryColor,
- ),
- title: const Text('版本信息', style: TextStyle(fontSize: 16)),
- trailing: _nextIcon(context),
- onTap: () => Navigator.of(context).pushNamed(UnitRouter.version_info),
- ),
- ],
- ),
- );
- }
-
-//SwitchListTile(
-// inactiveTrackColor: Colors.grey.withOpacity(0.3),
-// // inactiveThumbColor: Colors.white,
-// activeColor: Theme.of(context).primaryColor,
-// value: state.showBackGround,
-// secondary: Icon(
-// TolyIcon.icon_background,
-// color: Theme.of(context).primaryColor,
-// ),
-// title: const Text('显示背景', style: TextStyle(fontSize: 16)),
-// onChanged: (show) {
-// BlocProvider.of(context).switchShowBg(show);
-// },
-// )
-
- Widget _buildShowBg(BuildContext context) =>
- BlocBuilder(
- builder: (_, state) => TolySwitchListTile(
- secondary:Icon(
- TolyIcon.icon_background,
- color: Theme.of(context).primaryColor,
- ),
- title: const Text('显示背景', style: TextStyle(fontSize: 16,fontWeight: FontWeight.bold))
- , value: state.showBackGround, onChanged: (bool value) {
- BlocProvider.of(context).switchShowBg(value);
- },
- ),);
-
- Widget _buildShowOver(BuildContext context) =>
- BlocBuilder(
- builder: (_, state) => TolySwitchListTile(
- secondary:Icon(
- TolyIcon.icon_background,
- color: Theme.of(context).primaryColor,
- ),
- title: const Text('显示性能浮层', style: TextStyle(fontSize: 16,fontWeight: FontWeight.bold))
- , value: state.showPerformanceOverlay, onChanged: (bool value) {
- BlocProvider.of(context).switchShowOver(value);
- },
- ));
-
- Widget _buildShowTool(BuildContext context) =>
- BlocBuilder(
- builder: (_, state) => SwitchListTile(
- value: state.showOverlayTool,
- secondary: Icon(
- TolyIcon.icon_layout,
- color: Theme.of(context).primaryColor,
- ),
- title: const Text('显示浮动工具', style: TextStyle(fontSize: 16)),
- onChanged: (show) {
- if(show){
- OverlayToolWrapper.of(context).showFloating();
- }else{
- OverlayToolWrapper.of(context).hideFloating();
- }
- BlocProvider.of(context).switchShowTool(show);
- },
- ));
-
-
- Widget _nextIcon(BuildContext context) => Icon(Icons.chevron_right, color: Theme.of(context).primaryColor);
-}
diff --git a/lib/app/views/setting/theme_color_setting.dart b/lib/app/views/setting/theme_color_setting.dart
deleted file mode 100644
index 9ed91dc53..000000000
--- a/lib/app/views/setting/theme_color_setting.dart
+++ /dev/null
@@ -1,93 +0,0 @@
-import 'package:app/app.dart';
-import 'package:components/components.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:components/toly_ui/toly_ui.dart';
-
-/// create by 张风捷特烈 on 2020-04-10
-/// contact me by email 1981462002@qq.com
-/// 说明:
-
-class ThemeColorSettingPage extends StatelessWidget {
- const ThemeColorSettingPage({Key? key}) : super(key: key);
-
-
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- backgroundColor: UnitColor.scaffoldBgLight,
- appBar: const UnitAppbar(title:'主题色设置'),
- body: BlocBuilder(
- builder: (_, state) => _buildCell(
- context, Cons.kThemeColorSupport.keys.toList(), state.themeColor)),
- );
- }
-
- Widget _buildCell(
- BuildContext context, List themeColorSupport, MaterialColor color) {
- return GridView.count(
- padding: const EdgeInsets.only(top: 20, left: 10, right: 10),
- shrinkWrap: true,
- crossAxisCount: 2,
- mainAxisSpacing: 10,
- crossAxisSpacing: 10,
- childAspectRatio: 1.5,
- children: themeColorSupport
- .map((MaterialColor c) => FeedbackWidget(
- a: 0.95,
- duration: const Duration(milliseconds: 200),
- onPressed: () => BlocProvider.of(context).switchThemeColor(c),
- child: GridTile(
- header: Container(
- decoration: BoxDecoration(
- borderRadius: const BorderRadius.only(topLeft: Radius.circular(10),topRight: Radius.circular(10)),
- color: color == c
- ? Colors.blue.withAlpha(88):
- Colors.grey.withAlpha(55),
- ),
- padding: const EdgeInsets.only(left: 10, right: 5),
- height: 30,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- const Spacer(),
- Text(colorString(c),
- style: const TextStyle(
- color: Colors.white,
- )),
- const Spacer(),
- if (color == c) const Padding(
- padding: EdgeInsets.only(right:8.0),
- child: Circle(color: Colors.white,radius: 7,),
- )
- ],
- ),
- ),
- child: Container(
- decoration: BoxDecoration(
- borderRadius: const BorderRadius.all(Radius.circular(10)),
- gradient: LinearGradient(colors: [
- c.shade50,
- c.shade100,
- c.shade200,
- c.shade300,
- c.shade400,
- c.shade500,
- c.shade600,
- c.shade700,
- c.shade800,
- c.shade900,
- ])),
- alignment: const Alignment(0,0.35),
- child: Text(
- '${Cons.kThemeColorSupport[c]}',
- style: const TextStyle(fontSize: 18,color: Colors.white,fontWeight: FontWeight.bold),
- )),
- )))
- .toList(),
- );
- }
-
- String colorString(Color color) =>
- "#${color.value.toRadixString(16).padLeft(8, '0').toUpperCase()}";
-}
diff --git a/lib/app/views/setting/theme_model_setting.dart b/lib/app/views/setting/theme_model_setting.dart
deleted file mode 100644
index 40979d373..000000000
--- a/lib/app/views/setting/theme_model_setting.dart
+++ /dev/null
@@ -1,66 +0,0 @@
-import 'package:app/app.dart';
-import 'package:app/app/style/unit_color.dart';
-import 'package:components/project_ui/unit_app_bar.dart';
-import 'package:components/toly_ui/toly_ui.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-
-class ThemeModelSetting extends StatelessWidget {
- const ThemeModelSetting({Key? key}) : super(key: key);
-
- @override
- Widget build(BuildContext context) {
-
- ThemeMode mode = context.select((bloc) => bloc.state.themeMode);
- Color iconColor = Theme.of(context).primaryColor;
- return Scaffold(
- appBar: AppBar(title: Text('深色模式')),
- body: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Container( height: 15,),
- TolySwitchListTile(
- title: const Text('跟随系统', style: TextStyle(fontSize: 16,fontWeight: FontWeight.bold)),
- subtitle: Text(
- '开启后,将跟随系统打开或关闭深色模式',style: TextStyle(fontSize: 12,color: Colors.grey),
- ), value: mode == ThemeMode.system, onChanged: (bool value) {
- print("========value:$value==========");
- ThemeMode newModel;
- if(value){
- newModel = ThemeMode.system;
- }else{
- newModel = ThemeMode.light;
- }
- context.read().changeThemeMode(newModel);
- },
- // trailing: _nextIcon(context),
- // : () => Navigator.of(context).pushNamed(UnitRouter.font_setting),
- ),
- // AppStyle locale = Cons.kAppStyleStringMap.keys.toList()[index];
- // AppStyle style = BlocProvider.of(context).state.appStyle;
- // bool checked = style == locale;
- // Color color = Theme.of(context).primaryColor;
- Padding(
- padding: const EdgeInsets.only(left: 10,top: 16,bottom: 6),
- child: Text("手动设置"),
- ),
- ListTile(
- title: Text('浅色模式'),
- onTap: (){
- context.read().changeThemeMode(ThemeMode.light);
- },
- trailing: mode == ThemeMode.light ? Icon(Icons.check, size: 20, color: iconColor) : null,
- ),
- Divider(),
- ListTile(
- title: Text('深色模式'),
- onTap: (){
- context.read().changeThemeMode(ThemeMode.dark);
- },
- trailing: mode == ThemeMode.dark ? Icon(Icons.check, size: 20, color: iconColor) : null,
- )
- ],
- ),
- );;
- }
-}
diff --git a/lib/app/views/splash/standard_unit_splash.dart b/lib/app/views/splash/standard_unit_splash.dart
deleted file mode 100644
index bb05ecfb8..000000000
--- a/lib/app/views/splash/standard_unit_splash.dart
+++ /dev/null
@@ -1,137 +0,0 @@
-import 'dart:math';
-
-import 'package:app/app.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/services.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:utils/utils.dart';
-
-import 'package:widget_module/blocs/blocs.dart';
-
-import 'dart:ui' as ui;
-
-import 'package:widget_repository/widget_repository.dart';
-
-import 'flutter_unit_text.dart';
-
-/// create by 张风捷特烈 on 2020-03-07
-/// contact me by email 1981462002@qq.com
-/// 说明: app 闪屏页
-
-class StandardUnitSplash extends StatefulWidget {
- const StandardUnitSplash({Key? key}) : super(key: key);
-
- @override
- _StandardUnitSplashState createState() => _StandardUnitSplashState();
-}
-
-class _StandardUnitSplashState extends State
- with TickerProviderStateMixin {
- static const int _minCost = 1500;
-
- int _recorder = 0;
-
- final Paint paint = Paint()
- ..style = PaintingStyle.stroke
- ..shader = ui.Gradient.linear(
- const Offset(0, 0),
- const Offset(22, 0),
- [Colors.red, Colors.yellow, Colors.blue, Colors.green],
- [1 / 4, 2 / 4, 3 / 4, 1],
- TileMode.mirror,
- Matrix4.rotationZ(pi / 4).storage,
- );
-
- @override
- void initState() {
- super.initState();
- _recorder = DateTime.now().millisecondsSinceEpoch;
- }
-
- @override
- Widget build(BuildContext context) {
- final Size winSize = MediaQuery.of(context).size;
- return AnnotatedRegion(
- value: const SystemUiOverlayStyle(
- statusBarColor: Colors.transparent,
- statusBarIconBrightness: Brightness.dark),
- child: Material(
- child: BlocListener(
- listener: _listenStart,
- listenWhen: (p,n)=>p.dbPath.isEmpty&&n.dbPath.isNotEmpty,
- child: Column(
- children: [
- const Spacer(),
- Expanded(
- child: Wrap(
- direction: Axis.vertical,
- alignment: WrapAlignment.center,
- crossAxisAlignment: WrapCrossAlignment.center,
- children: [
- Stack(
- children: [
- Text(
- "U",
- style: TextStyle(
- fontSize: 26,
- height: 1,
- fontWeight: FontWeight.bold,
- foreground: paint),
- ),
- const FlutterLogo(size: 60),
- ],
- ),
- const SizedBox(
- height: 20,
- ),
- _buildFlutterUnitText(winSize.height, winSize.width),
- ],
- )),
- Expanded(
- child: Stack(
- alignment: Alignment.bottomCenter,
- children: [
- Positioned(
- bottom: 15,
- child: Wrap(
- direction: Axis.vertical,
- alignment: WrapAlignment.center,
- crossAxisAlignment: WrapCrossAlignment.center,
- children: const [
- Text("Power By 张风捷特烈",
- style: UnitTextStyle.splashShadows),
- Text("· 2021 · @编程之王 ",
- style: UnitTextStyle.splashShadows),
- ],
- )),
- ],
- ))
- ],
- )),
- ),
- );
- }
-
- Widget _buildFlutterUnitText(double winH, double winW) {
- return FlutterUnitText(
- text: StrUnit.appName,
- color: Theme.of(context).primaryColor,
- );
- }
-
- // 监听资源加载完毕,启动,触发事件
- void _listenStart(BuildContext context, AppState state) {
- HttpUtil.instance.rebase(PathUnit.baseUrl);
- int cost = DateTime.now().millisecondsSinceEpoch - _recorder;
- BlocProvider.of(context)
- .add(const EventTabTap(WidgetFamily.statelessWidget));
- BlocProvider.of(context).add(const EventLoadLikeData());
- BlocProvider.of(context).add(const EventLoadCategory());
-
- // 启动耗时小于 _minCost 时,等待 delay 毫秒
- int delay = cost < _minCost ? _minCost - cost : 0;
- Future.delayed(Duration(milliseconds: delay)).then((value) {
- Navigator.of(context).pushReplacementNamed(UnitRouter.nav);
- });
- }
-}
diff --git a/lib/awesome/listenable/change_notifier_02/main.dart b/lib/awesome/listenable/change_notifier_02/main.dart
deleted file mode 100644
index 3d04b86e5..000000000
--- a/lib/awesome/listenable/change_notifier_02/main.dart
+++ /dev/null
@@ -1,38 +0,0 @@
-import 'package:app/app.dart';
-import 'package:flutter/material.dart';
-
-import 'notifier/download_data_scope.dart';
-import 'notifier/progress_value_notifier.dart';
-import 'page/home/home_page.dart';
-
-void main(){
- WidgetsFlutterBinding.ensureInitialized();
- runApp(const MyApp());
- WindowsAdapter.setSize();
-}
-
-class MyApp extends StatelessWidget{
- const MyApp({super.key});
-
- @override
- Widget build(BuildContext context) {
- return DownloadDataScope(
- notifier: ProgressValueNotifier(),
- child: MaterialApp(
- debugShowCheckedModeBanner: false,
- theme: ThemeData(
- colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
- useMaterial3: true,
- ),
- home: const ChangeNotifierHome02(),
- ),
- );
- }
-}
-
-
-
-
-
-
-
diff --git a/lib/code_gen/bloc/state.dart b/lib/code_gen/bloc/state.dart
deleted file mode 100644
index e7bac1b94..000000000
--- a/lib/code_gen/bloc/state.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:flutter_unit/code_gen/model/class.dart';
-
-class ClassGenBloc extends Cubit{
-
- ClassGenBloc():super(Class(fields: [], name: ''));
-
-
-
-}
\ No newline at end of file
diff --git a/lib/code_gen/desk_widget_top_bar.dart b/lib/code_gen/desk_widget_top_bar.dart
deleted file mode 100644
index 8654630c1..000000000
--- a/lib/code_gen/desk_widget_top_bar.dart
+++ /dev/null
@@ -1,72 +0,0 @@
-import 'package:app/app.dart';
-import 'package:components/toly_ui/toly_ui.dart';
-import 'package:flutter/material.dart';
-
-
-
-class DeskCodeGenTopBar extends StatefulWidget {
- final ValueChanged onTabPressed;
- final VoidCallback onTapGen;
-
- const DeskCodeGenTopBar({Key? key,required this.onTabPressed, required this.onTapGen}) : super(key: key);
-
- @override
- State createState() => _DeskCodeGenTopBarState();
-}
-
-class _DeskCodeGenTopBarState extends State with SingleTickerProviderStateMixin {
- late TabController tabController;
-
- static const List _tabs = ['IconFont', '数据类' , '状态管理', 'Json 解析',];
-
- @override
- void initState() {
- super.initState();
- tabController = TabController(length: _tabs.length, vsync: this);
- }
-
- @override
- Widget build(BuildContext context) {
- Color themeColor = Theme.of(context).primaryColor;
-
- bool isDark = Theme.of(context).brightness == Brightness.dark;
- return DragToMoveAreaNoDouble(
- child: Container(
- padding: const EdgeInsets.symmetric(horizontal: 20),
- height: 64,
- color: isDark?Color(0xff2C3036):Colors.white,
- child: Row(
- children: [
- SizedBox(
- width: 350,
- child: TabBar(
- onTap: widget.onTabPressed,
- indicatorSize: TabBarIndicatorSize.label,
- labelPadding: const EdgeInsets.symmetric(horizontal: 6),
- isScrollable: false,
- indicator: RoundRectTabIndicator(
- borderSide: BorderSide(color: themeColor, width: 3),
- ),
- labelStyle: const TextStyle(
- fontSize: 14,
- fontWeight: FontWeight.bold,
- ),
- controller: tabController,
- labelColor: themeColor,
- indicatorWeight: 3,
- unselectedLabelColor: Colors.grey,
- indicatorColor: themeColor,
- tabs:
- _tabs.map((String name) => Tab(text: name)).toList(),
- ),
- ),
- Spacer(),
-
- const SizedBox(width: 20,),
- WindowButtons(),
- ],
- ),
- ),
- );
- }
-}
diff --git a/lib/components/top_bar/desk_simple_top_bar.dart b/lib/components/top_bar/desk_simple_top_bar.dart
deleted file mode 100644
index 0cd3080bd..000000000
--- a/lib/components/top_bar/desk_simple_top_bar.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-import 'package:app/app.dart';
-import 'package:flutter/material.dart';
-
-class SimpleDeskTopBar extends StatelessWidget {
- final Widget? leading;
-
- const SimpleDeskTopBar({super.key, this.leading});
-
- @override
- Widget build(BuildContext context) {
- return DragToMoveAreaNoDouble(
- child: Container(
- padding: const EdgeInsets.symmetric(horizontal: 20),
- height: 64,
- color: Colors.white,
- child: Row(
- children: [
- if (leading != null) leading!,
- const Spacer(),
- const SizedBox(
- width: 20,
- ),
- const WindowButtons(),
- ],
- ),
- ),
- );
- }
-}
diff --git a/lib/main.dart b/lib/main.dart
index a0544e0e8..442228576 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,16 +1,3 @@
-import 'package:app/app.dart';
-import 'package:flutter/gestures.dart';
-import 'package:flutter/material.dart';
-
-import 'app/bloc_wrapper.dart';
-import 'app/flutter_unit.dart';
-
-
-void main() {
- WidgetsFlutterBinding.ensureInitialized();
- //滚动性能优化 1.22.0
- GestureBinding.instance.resamplingEnabled = true;
- runApp(const BlocWrapper(child: FlutterUnit()));
- WindowsAdapter.setSize();
-}
+import 'src/starter/fx_application.dart';
+void main(List args) => const FxApplication().run(args);
diff --git a/lib/painter_system/gallery_factory.dart b/lib/painter_system/gallery_factory.dart
deleted file mode 100644
index dbdddfcf0..000000000
--- a/lib/painter_system/gallery_factory.dart
+++ /dev/null
@@ -1,270 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter_unit/painter_system/anim/spring_widget.dart';
-
-import 'anim/bezier3_player/bezier3_palyer.dart';
-import 'anim/circle_halo.dart';
-import 'anim/curve_shower/curve_anim_shower.dart';
-import 'anim/draw_path.dart';
-import 'anim/dundun_path.dart';
-import 'anim/rotate_by_point/rotate_by_point.dart';
-import 'art/circle_packing.dart';
-import 'art/cubic_disarray.dart';
-import 'art/hypnotic_squares.dart';
-import 'art/joy_division.dart';
-import 'art/piet_mondrian.dart';
-import 'art/tiled_lines.dart';
-import 'art/triangular_mesh.dart';
-import 'art/un_deux_trois.dart';
-import 'base/clock_widget.dart';
-import 'base/digital/digital_shower.dart';
-import 'base/draw_grid_axis.dart';
-import 'base/draw_path_fun.dart';
-import 'base/draw_picture.dart';
-
-import 'base/n_side/n_side_page.dart';
-import 'base/polar/polar_painter_widget.dart';
-import 'base/windmill.dart';
-import 'fun/bufeng/bufeng_panel.dart';
-import 'fun/dundun_view.dart';
-import 'fun/random_portrait.dart';
-import 'fun/stemp/stamp_paper.dart';
-import 'particle/random/random_particle.dart';
-import 'particle/split/particle_split.dart';
-import 'particle/split_img/split_image.dart';
-import 'picture_frame.dart';
-
-/// create by 张风捷特烈 on 2020/12/5
-/// contact me by email 1981462002@qq.com
-/// 说明:
-///
-
-enum GalleryType { base, anim, particle, fun, art }
-
-class GalleryFactory {
- static List getGalleryByName(GalleryType type) {
- switch (type) {
- case GalleryType.base:
- return const [
- FrameShower(
- title: "The Chaos",
- author: "张风捷特烈",
- srcUrl: "/base/draw_picture.dart",
- info: "本样例介绍如何进行图片的绘制:通过加载图片并将图片资源绘制到指定的区域。在上层绘制一批 45° 倾角的栅格线,来练习线条的绘制。",
- content: DrawPicture()),
- FrameShower(
- title: "数字显示管",
- author: "张风捷特烈",
- srcUrl: "/base/digital",
- info: "本样例介绍如何绘制 LED 数字显示管,以此练习对路径 Path 的使用、变换、组合,以及组件封装的知识。是一个非常好的绘制案例。",
- content: DigitalShower()),
- FrameShower(
- title: "旋转风车",
- author: "张风捷特烈",
- srcUrl: "/base/windmill.dart",
- info: "本样例介绍如何进行简单的路径绘制,以及画板的旋转,再结合动画让风车旋转。这是一个非常精简的绘制与动画结合的案例。",
- content: WindmillWidget()),
- FrameShower(
- title: "平面直角坐标系",
- author: "张风捷特烈",
- srcUrl: "/base/draw_grid_axis.dart",
- info:
- "本样例介绍如何使用线路径和文字绘制网格坐标系,并将绘制对象进行封装,方便重用。坐标系也会在绘制时提供参考,入门必备。",
- content: DrawGridAxis()),
- FrameShower(
- title: "平面极坐标系",
- author: "张风捷特烈",
- srcUrl: "/base/polar",
- info:
- "本样例介绍如何使用绘制平面的极坐标系,并根据函数方程收集极坐标进行绘制。",
- content: PolarPainterWidget()),
- FrameShower(
- title: "曲线拟合",
- author: "张风捷特烈",
- srcUrl: "/base/draw_path_fun.dart",
- info: "本样例介绍如何使用路径对函数曲线进行绘制,通过函数曲线上的少量点通过贝塞尔曲线进行拟合。",
- content: DrawPathFun()),
- FrameShower(
- title: "圆中取形",
- author: "张风捷特烈",
- srcUrl: "/base/n_side",
- info: "本样例介绍如何在圆中收集点位,绘制正多边形,是练习绘制及形成路径的很好案例。\n特殊操作:+、- 修改边数",
- content: NSidePage()),
- FrameShower(
- title: "随机对称图",
- author: "张风捷特烈",
- srcUrl: '/fun/random_portrait.dart',
- info: "本样例介绍绘制矩形及随机数处理。通过点位集合确定矩形位置信息,将其绘制出来。可以练习对数据的控制能力。\n特殊操作:点击随机生成",
- content: RandomPortrait()),
- FrameShower(
- title: "简单时钟",
- author: "张风捷特烈",
- srcUrl: '/base/clock_widget.dart',
- info: "本样例通过时钟的绘制,练习 Flutter 中旋转刻度类型的绘制技巧,并通过动画使表盘指针转动。",
- content: ClockWidget()),
- ];
- case GalleryType.anim:
- return const [
- FrameShower(
- title: "手势弹簧",
- author: "张风捷特烈",
- srcUrl: '/anim/spring_widget.dart',
- info: "本样例介绍如何绘制弹簧,通过触点竖直拖拽拉伸、压缩,放手时进行恢复动画,是一个很好的综合小案例。\n特殊操作:上下拖拽伸缩弹簧",
- content: SpringWidget()),
- FrameShower(
- title: "绕定点旋转",
- author: "张风捷特烈",
- srcUrl: '/anim/rotate_by_point',
- info: "本样例介绍如何根据以某个点为中心,进行旋转运动。以此学习两点间的角度在绘制中的应用。\n特殊操作:点击运行",
- content: RotateByPointWidget()),
- FrameShower(
- title: "流光",
- author: "张风捷特烈",
- srcUrl: '/anim/circle_halo.dart',
- info: "本样例介绍如何在绘制中使用着色器和过滤器,并通过动画进行数值变化达到旋转流光效果。",
- content: CircleHalo()),
- FrameShower(
- title: "曲线路径动画",
- author: "张风捷特烈",
- srcUrl: '/anim/draw_path.dart',
- info: "本样例介绍如何使用路径绘制函数曲线,并使用路径测量进行动画",
- content: DrawPath()),
- FrameShower(
- title: "冰墩墩线条动画",
- author: "张风捷特烈",
- srcUrl: '/anim/dundun_path.dart',
- info: "本样例会绘制 2022 年北京冬奥会吉祥物冰墩墩的路径,并使用路径测量进行动画。\n特殊操作:点击运行",
- content: DunDunPathPage()),
- FrameShower(
- title: "Bezier3 演示",
- author: "张风捷特烈",
- srcUrl: '/anim/bezier3_player',
- info: "本样例介绍如何绘制三次贝塞尔曲线,通过触点判断某点是否激活,据此控制点的位置达到拖动控制效果。\n特殊操作:单击绘点,双击清除",
- content: Bezier3Player()),
- FrameShower(
- title: "动画曲线散点图",
- author: "张风捷特烈",
- srcUrl: '/anim/curve_shower',
- info: "本样例通过直观的方式,来查看动画曲线 curve 的作用效果,让大家对动画有更深的理解。\n特殊操作:点击运行",
- content: CurveAnimShower()),
-
- ];
- case GalleryType.particle:
- return const [
- FrameShower(
- title: "随机粒子生成器",
- author: "张风捷特烈",
- srcUrl: '/particle/random',
- info: "本样例介绍如何创建随机粒子及边界反弹逻辑处理,是学习粒子运动非常好的入门案例。\n特殊操作:单击停止/运行",
- content: RandomParticle()),
- FrameShower(
- title: "粒子分裂",
- author: "张风捷特烈",
- srcUrl: '/particle/split',
- info: "本样例介绍如何对个粒子进行碰撞检测,并分裂处多个粒子,是一个比较有趣的案例。\n特殊操作:单击重置",
- content: ParticleSplit()),
- FrameShower(
- title: "图片粒子分裂",
- author: "张风捷特烈",
- srcUrl: '/particle/split_img',
- info: "本样例介绍将图片使用粒子表示,并对粒子进行动画处理,达到爆炸的效果。\n特殊操作:单击运行",
- content: SplitImage()),
- ];
- case GalleryType.fun:
- return const[
- FrameShower(
- title: "Random Portrait",
- author: "张风捷特烈",
- srcUrl: '/fun/random_portrait.dart',
- info: "本样例介绍绘制矩形及随机数处理。通过点位集合确定矩形位置信息,将其绘制出来。可以练习对数据的控制能力。\n特殊操作:点击随机生成",
- content: RandomPortrait()),
- FrameShower(
- title: "冰墩墩",
- author: "张风捷特烈",
- srcUrl: '/fun/dundun_view.dart',
- info: "本样例是绘制 2022 年北京冬奥会吉祥物冰墩墩的形体,从中可以学到路径绘制、渐变色等知识。",
- content: DunDunView()),
- FrameShower(
- title: "蒲丰投针试验",
- author: "张风捷特烈",
- srcUrl: '/fun/bufeng',
- info: "本样实现蒲丰投针试验的测试过程,根据概率来估算圆周率。其中可以学习到一些绘制小技巧已经数据的逻辑处理。",
- content: BufengPanel()),
- FrameShower(
- title: "井字棋",
- author: "张风捷特烈",
- srcUrl: '/fun/stemp',
- info: "本例通过井字棋的绘制与逻辑校验,集合了手势、绘制、动画、校验等重要的技能,是一个非常好的联系案例。\n特殊操作:双击重置",
- content: StampPaper()),
- ];
- case GalleryType.art:
- return const [
- FrameShower(
- title: "Tiled Line",
- author: "generativeartistry.com",
- srcUrl: '/art/tiled_lines.dart',
- info:
- "本样例根源来自generativeartistry.com的tiled-lines,由xrr2016使用Flutter实现。仓库地址:flutter-generative-artistry",
- content: TiledLines(),
- ),
- FrameShower(
- title: "Joy Division",
- author: "generativeartistry.com",
- srcUrl: '/art/joy_division.dart',
- info:
- "本样例根源来自generativeartistry.com的joy-division,由xrr2016使用Flutter实现。仓库地址:flutter-generative-artistry",
- content: JoyDivision(),
- ),
- FrameShower(
- title: "Cubic Disarray",
- author: "generativeartistry.com",
- srcUrl: '/art/cubic_disarray.dart',
- info:
- "本样例根源来自generativeartistry.com的cubic-disarray,由xrr2016使用Flutter实现。仓库地址:flutter-generative-artistry",
- content: CubicDisarray(),
- ),
- FrameShower(
- title: "Triangular Mesh",
- author: "generativeartistry.com",
- srcUrl: '/art/triangular_mesh.dart',
- info:
- "本样例根源来自generativeartistry.com的triangular-mesh,由xrr2016使用Flutter实现。仓库地址:flutter-generative-artistry",
- content: TriangularMesh(),
- ),
- FrameShower(
- title: "Un Deux Trois",
- srcUrl: '/art/un_deux_trois.dart',
- author: "generativeartistry.com",
- info:
- "本样例根源来自generativeartistry.com的un-deux-trois,由xrr2016使用Flutter实现。仓库地址:flutter-generative-artistry",
- content: UnDeuxTrois(),
- ),
- FrameShower(
- title: "Circle Packing",
- author: "generativeartistry.com",
- srcUrl: '/art/circle_packing.dart',
- info:
- "本样例根源来自generativeartistry.com的circle-packing,由xrr2016使用Flutter实现。仓库地址:flutter-generative-artistry",
- content: CirclePacking(),
- ),
- FrameShower(
- title: "Hypnotic Squares",
- author: "generativeartistry.com",
- srcUrl: '/art/hypnotic_squares.dart',
- info:
- "本样例根源来自generativeartistry.com的hypnotic-squares,由xrr2016使用Flutter实现。仓库地址:flutter-generative-artistry",
- content: HypnoticSquares(),
- ),
- FrameShower(
- title: "Piet Mondrian",
- author: "generativeartistry.com",
- srcUrl: '/art/piet_mondrian.dart',
- info:
- "本样例根源来自generativeartistry.com的piet-mondrian,由xrr2016使用Flutter实现。仓库地址:flutter-generative-artistry",
- content: PietMondrian(),
- )
- ];
- default:
- return [];
- }
- }
-}
diff --git a/lib/point_system/api/issues_api.dart b/lib/point_system/api/issues_api.dart
deleted file mode 100644
index 86f51578a..000000000
--- a/lib/point_system/api/issues_api.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-import 'dart:convert';
-
-import 'package:dio/dio.dart';
-import 'package:flutter_unit/point_system/github_model/github_model.dart';
-
-
-/// create by 张风捷特烈 on 2020/6/17
-/// contact me by email 1981462002@qq.com
-/// 说明:
-
-const kBaseUrl = 'http://toly1994.com:8080/api/v1';
-
-class IssuesApi {
- static Dio dio = Dio(BaseOptions(baseUrl: kBaseUrl));
-
- static Future getRepoFlutterUnit() async {
- Response rep = await dio.get('/repository/name/FlutterUnit');
- dynamic repoStr = rep.data['data']['repositoryData'];
- return Repository.fromJson(json.decode(repoStr));
- }
-
- static Future> getIssues(
- {int page = 1, int pageSize = 100}) async {
- List res = (await dio.get('/point',
- queryParameters: {"page": page, "pageSize": pageSize}))
- .data['data'] as List;
- return res.map((e) => Issue.fromJson(json.decode(e['pointData']))).toList();
- }
-
- static Future> getIssuesComment(int pointId) async {
- List res = (await dio.get('/pointComment/$pointId')).data['data'] as List;
- return res
- .map((e) => IssueComment.fromJson(json.decode(e['pointCommentData'])))
- .toList();
- }
-}
diff --git a/lib/point_system/blocs/point_bloc/point_bloc.dart b/lib/point_system/blocs/point_bloc/point_bloc.dart
deleted file mode 100644
index fd4d32815..000000000
--- a/lib/point_system/blocs/point_bloc/point_bloc.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:flutter_unit/point_system/api/issues_api.dart';
-
-import 'point_event.dart';
-import 'point_state.dart';
-
-
-/// create by 张风捷特烈 on 2020-09-03
-/// contact me by email 1981462002@qq.com
-/// 说明:
-
-class PointBloc extends Bloc {
- PointBloc() : super(PointLoading()){
- on(_onEventLoadPoint);
- }
-
- void _onEventLoadPoint(PointEvent event,Emitter emit) async{
- emit( PointLoading());
- try {
- final issues = await IssuesApi.getIssues();
- emit( PointLoaded(issues));
- } catch (err) {
- print(err);
- emit( PointLoadFailure(err.toString()));
- }
- }
-}
diff --git a/lib/point_system/blocs/point_bloc/point_event.dart b/lib/point_system/blocs/point_bloc/point_event.dart
deleted file mode 100644
index 5c686d59c..000000000
--- a/lib/point_system/blocs/point_bloc/point_event.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-import 'package:equatable/equatable.dart';
-
-/// create by 张风捷特烈 on 2020/9/3
-/// contact me by email 1981462002@qq.com
-/// 说明:
-
-abstract class PointEvent extends Equatable {
-
-}
-
-class EventLoadPoint extends PointEvent{
-
- @override
- List