mirror of
https://github.com/alibaba/flutter-go.git
synced 2025-06-06 10:37:47 +08:00
add file
This commit is contained in:
190
README.md
190
README.md
@ -1,36 +1,160 @@
|
||||
## Flutter 菜鸟手册
|
||||
# flutter-common-widgets-app
|
||||
|
||||
> 帮助开发者快速上手 Flutter
|
||||
|
||||
### 背景
|
||||
|
||||
#### Flutter 是什么
|
||||
|
||||
2018年6月21日Google发布Flutter首个release预览版,作为Google baba大力推出的一种全新的响应式,跨平台,高性能的移动开发框架。Flutter是一个跨平台的移动UI框架,旨在帮助开发者使用一套代码开发高性能、高保真的Android和iOS应用。
|
||||
|
||||
flutter优点主要包括:
|
||||
- 跨平台
|
||||
- 开源
|
||||
- Hot Reload、响应式框架、及其丰富的控件以及开发工具
|
||||
- 灵活的界面设计以及控件组合
|
||||
- 借助可以移植的GPU加速的渲染引擎以及高性能ARM代码运行时已达到高质量的用户体验
|
||||
|
||||
#### 菜鸟手册的由来
|
||||
|
||||
- Flutter学习资料太少,对于英文不好的同学相对来说比较困难
|
||||
- 官网文档示例不够健全,不够直观
|
||||
|
||||
#### 菜鸟手册的优势
|
||||
|
||||
- 详解常用widget多达 **130+** 个
|
||||
- 配套 Demo 详解 widget 常规用法
|
||||
|
||||
### app 预览
|
||||
|
||||
<img src="https://img.alicdn.com/tfs/TB1x4gdASzqK1RjSZFHXXb3CpXa-1080-2340.jpg" width=200> <img src="https://img.alicdn.com/tfs/TB1xioCANnaK1RjSZFtXXbC2VXa-1080-2340.jpg" width=200> <img src="https://img.alicdn.com/tfs/TB1XFwcAOrpK1RjSZFhXXXSdXXa-1080-2340.jpg" width=200> <img src="https://img.alicdn.com/tfs/TB1Hf7aAPTpK1RjSZKPXXa3UpXa-1080-2340.jpg" width=200>
|
||||
|
||||
### 团队
|
||||
|
||||
power by [阿里拍卖前端团队](https://github.com/alibaba-paimai-frontend)<img src="https://img.alicdn.com/tfs/TB1foEhAMHqK1RjSZJnXXbNLpXa-166-166.png" width=20 height=20>
|
||||
### 使用背景
|
||||
* 鉴于目前flutter官方庞大的小部件(widget)系统以及api文档,只有文字描述,而没有可视化实例。
|
||||
* 我们开发这套app,可以系统的看到常用小部件(widget)的用法。
|
||||
* 辅助初学者更快上手,flutter官方小部件(widget)
|
||||
|
||||
|
||||
|
||||
### 参考资料
|
||||
|
||||
* [flutter-widgets的官方库地址]( https://docs.flutter.kim/widgets/widgets-library.html )
|
||||
* [flutter-widgets的官方目录集]( http://doc.flutter-dev.cn/widgets/ )
|
||||
* [sqlitestudio 本地可视化工具] (https://sqlitestudio.pl/index.rvt)
|
||||
|
||||
### 分支命名及使用规范
|
||||
|
||||
* 分支命名规范
|
||||
- 自己开发分支命名统一为 username ,如:yifeng
|
||||
- 分支两条主线为 Master分支和develop分支
|
||||
- Master作为发布分支,develop作为开发测试分支、自己开发分支从dev checkout出去,发布即 merge to master
|
||||
|
||||
* 分支合并规范
|
||||
- 从最新的develop分支checkout出自己的开发分支
|
||||
- 在自己开发开发分支开发完成后,先去develop分支pull最新代码,
|
||||
- 将develop 分支最新代码 merge 到自己分支,确保无冲突
|
||||
- 再切回develop分支merge自己开发分支代码,确保无冲突,且能正常运行
|
||||
|
||||
### commit 提交规范
|
||||
* $git cz
|
||||
|
||||
* 用于说明 commit 的类别,只允许使用下面7个标识。
|
||||
|
||||
- feat:新功能(feature)
|
||||
|
||||
- fix:修补bug
|
||||
|
||||
- docs:文档(documentation)
|
||||
|
||||
- style: 格式(不影响代码运行的变动)
|
||||
|
||||
- refactor:重构(即不是新增功能,也不是修改bug的代码变动)
|
||||
|
||||
- test:增加测试
|
||||
|
||||
- chore:构建过程或辅助工具的变动
|
||||
|
||||
|
||||
### 代码规范
|
||||
* 文件命名规范
|
||||
- 文件命名使用下划线命名法,如:hello_world
|
||||
- 请使用英文进行命名,不允许使用拼音。命名要求具有可读性,尽量避免使用缩写与数字
|
||||
- 未完待续
|
||||
|
||||
* 代码编码规范
|
||||
- 文件编码统一使用 UTF-8 编码;
|
||||
- 前端编码采用首字母小写驼峰法. Widget Class 必须采用首字母大写驼峰法.
|
||||
|
||||
### 文件目录结构(以LIb文件说明)
|
||||
|
||||
- lib
|
||||
- main.dart 入口文件
|
||||
- common 公共的method
|
||||
- components widget
|
||||
- generated
|
||||
- model 存放模型, 不应该加入逻辑层
|
||||
- router 路由
|
||||
- views 展示界面
|
||||
- widget (与components概念重合,废弃)
|
||||
|
||||
``` javascript
|
||||
├── main.dart //入口文件
|
||||
├── common 公共的method
|
||||
│ ├── Style.dart
|
||||
│ ├── eventBus.dart
|
||||
│ ├── provider.dart
|
||||
│ └── sql.dart
|
||||
├── components //app展示框架用到的组件
|
||||
│ ├── Input.dart
|
||||
│ ├── List.dart
|
||||
│ ├── Pagination.dart
|
||||
│ ├── Pagination2.dart
|
||||
│ ├── SearchInput.dart
|
||||
│ └── homeBanner.dart
|
||||
├── generated
|
||||
│ └── i18n.dart
|
||||
├── model //本地存放模型, 不应该加入逻辑层
|
||||
│ ├── base.dart
|
||||
│ ├── cat.dart
|
||||
│ ├── story.dart
|
||||
│ └── widget.dart
|
||||
├── routers //路由
|
||||
│ ├── application.dart
|
||||
│ ├── router_handler.dart
|
||||
│ └── routers.dart
|
||||
├── views //app展示界面
|
||||
│ ├── Detail.dart
|
||||
│ ├── FirstPage.dart
|
||||
│ ├── FourthPage.dart
|
||||
│ ├── ThirdPage.dart
|
||||
│ ├── category.dart
|
||||
│ ├── demos
|
||||
│ │ ├── home.dart
|
||||
│ │ └── layout
|
||||
│ │ ├── SamplePage.dart
|
||||
│ │ └── layout_type.dart
|
||||
│ └── widgetPage.dart
|
||||
└── widgets
|
||||
└── ... //下面详细说明
|
||||
```
|
||||
|
||||
``` javascript
|
||||
└── widgets // 对flutter所有元素和组件的分类
|
||||
├── 404.dart
|
||||
├── index.dart // widgets 的总入口文件
|
||||
├── components // 组件的分类 (区别于上面的components)
|
||||
│ └── index.dart
|
||||
├── elements // 基础元素的分类
|
||||
│ ├── index.dart // elements下的 elements 类型入口文件
|
||||
│ ├── Form // elements下的 From 类型集合
|
||||
│ │ ├── Button // button 元素,里面是 文件夹代表类名/index.dart
|
||||
│ │ │ ├── FlatButton
|
||||
│ │ │ │ └── index.dart
|
||||
│ │ │ ├── RaisedButton
|
||||
│ │ │ │ └── index.dart
|
||||
│ │ │ └── index.dart
|
||||
│ │ ├── CheckBox
|
||||
│ │ ├── Input
|
||||
│ │ ├── Radio
|
||||
│ │ ├── Slider
|
||||
│ │ ├── Switch
|
||||
│ │ ├── Text
|
||||
│ │ └── index.dart
|
||||
│ ├── Frame // elements下的 Frame 类型集合
|
||||
│ │ ├── Align
|
||||
│ │ ├── Axis
|
||||
│ │ ├── Box
|
||||
│ │ ├── Expanded
|
||||
│ │ ├── Layout
|
||||
│ │ ├── Stack
|
||||
│ │ ├── Table
|
||||
│ │ └── spacing
|
||||
│ └── Media // elements下的 Media 类型集合
|
||||
│ ├── Canvas
|
||||
│ ├── Icon
|
||||
│ └── Image
|
||||
└── themes
|
||||
└── index.dart
|
||||
```
|
||||
|
||||
```javascript
|
||||
widget 里的文件结构,用来存放封装的逻辑组件, 文件目录应为, 类比rax
|
||||
- widget // widget 下详细元素或组件的目录结构
|
||||
- hello-world // 例如
|
||||
- mods // (可选, 子模块)
|
||||
- mocks // (可选)
|
||||
- utils // (可选, 存放暂时的私有method)
|
||||
- schema
|
||||
- index.dart
|
||||
```
|
BIN
assets/app.db
BIN
assets/app.db
Binary file not shown.
189
dev.md
189
dev.md
@ -1,160 +1,37 @@
|
||||
# flutter-common-widgets-app
|
||||
## Flutter 菜鸟手册
|
||||
|
||||
### 使用背景
|
||||
* 鉴于目前flutter官方庞大的小部件(widget)系统以及api文档,只有文字描述,而没有可视化实例。
|
||||
* 我们开发这套app,可以系统的看到常用小部件(widget)的用法。
|
||||
* 辅助初学者更快上手,flutter官方小部件(widget)
|
||||
> 帮助开发者快速上手 Flutter
|
||||
|
||||
### 背景
|
||||
|
||||
#### Flutter 是什么
|
||||
|
||||
2018年6月21日Google发布Flutter首个release预览版,作为Google baba大力推出的一种全新的响应式,跨平台,高性能的移动开发框架。Flutter是一个跨平台的移动UI框架,旨在帮助开发者使用一套代码开发高性能、高保真的Android和iOS应用。
|
||||
|
||||
flutter优点主要包括:
|
||||
- 跨平台
|
||||
- 开源
|
||||
- Hot Reload、响应式框架、及其丰富的控件以及开发工具
|
||||
- 灵活的界面设计以及控件组合
|
||||
- 借助可以移植的GPU加速的渲染引擎以及高性能ARM代码运行时已达到高质量的用户体验
|
||||
|
||||
#### 菜鸟手册的由来
|
||||
|
||||
- Flutter学习资料太少,对于英文不好的同学相对来说比较困难
|
||||
- 官网文档示例不够健全,不够直观
|
||||
|
||||
#### 菜鸟手册的优势
|
||||
|
||||
- 详解常用widget多达 **130+** 个
|
||||
- 配套 Demo 详解 widget 常规用法
|
||||
|
||||
### app 预览
|
||||
|
||||
<img src="https://img.alicdn.com/tfs/TB1x4gdASzqK1RjSZFHXXb3CpXa-1080-2340.jpg" width=200> <img src="https://img.alicdn.com/tfs/TB1xioCANnaK1RjSZFtXXbC2VXa-1080-2340.jpg" width=200> <img src="https://img.alicdn.com/tfs/TB1XFwcAOrpK1RjSZFhXXXSdXXa-1080-2340.jpg" width=200> <img src="https://img.alicdn.com/tfs/TB1Hf7aAPTpK1RjSZKPXXa3UpXa-1080-2340.jpg" width=200>
|
||||
|
||||
### 团队
|
||||
|
||||
power by [阿里拍卖前端团队](https://github.com/alibaba-paimai-frontend)<img src="https://img.alicdn.com/tfs/TB1foEhAMHqK1RjSZJnXXbNLpXa-166-166.png" width=20 height=20>
|
||||
|
||||
|
||||
|
||||
### 参考资料
|
||||
|
||||
* [flutter-widgets的官方库地址]( https://docs.flutter.kim/widgets/widgets-library.html )
|
||||
* [flutter-widgets的官方目录集]( http://doc.flutter-dev.cn/widgets/ )
|
||||
* [sqlitestudio 本地可视化工具] (https://sqlitestudio.pl/index.rvt)
|
||||
|
||||
### 分支命名及使用规范
|
||||
|
||||
* 分支命名规范
|
||||
- 自己开发分支命名统一为 username ,如:yifeng
|
||||
- 分支两条主线为 Master分支和develop分支
|
||||
- Master作为发布分支,develop作为开发测试分支、自己开发分支从dev checkout出去,发布即 merge to master
|
||||
|
||||
* 分支合并规范
|
||||
- 从最新的develop分支checkout出自己的开发分支
|
||||
- 在自己开发开发分支开发完成后,先去develop分支pull最新代码,
|
||||
- 将develop 分支最新代码 merge 到自己分支,确保无冲突
|
||||
- 再切回develop分支merge自己开发分支代码,确保无冲突,且能正常运行
|
||||
|
||||
### commit 提交规范
|
||||
* $git cz
|
||||
|
||||
* 用于说明 commit 的类别,只允许使用下面7个标识。
|
||||
|
||||
- feat:新功能(feature)
|
||||
|
||||
- fix:修补bug
|
||||
|
||||
- docs:文档(documentation)
|
||||
|
||||
- style: 格式(不影响代码运行的变动)
|
||||
|
||||
- refactor:重构(即不是新增功能,也不是修改bug的代码变动)
|
||||
|
||||
- test:增加测试
|
||||
|
||||
- chore:构建过程或辅助工具的变动
|
||||
|
||||
|
||||
### 代码规范
|
||||
* 文件命名规范
|
||||
- 文件命名使用下划线命名法,如:hello_world
|
||||
- 请使用英文进行命名,不允许使用拼音。命名要求具有可读性,尽量避免使用缩写与数字
|
||||
- 未完待续
|
||||
|
||||
* 代码编码规范
|
||||
- 文件编码统一使用 UTF-8 编码;
|
||||
- 前端编码采用首字母小写驼峰法. Widget Class 必须采用首字母大写驼峰法.
|
||||
|
||||
### 文件目录结构(以LIb文件说明)
|
||||
|
||||
- lib
|
||||
- main.dart 入口文件
|
||||
- common 公共的method
|
||||
- components widget
|
||||
- generated
|
||||
- model 存放模型, 不应该加入逻辑层
|
||||
- router 路由
|
||||
- views 展示界面
|
||||
- widget (与components概念重合,废弃)
|
||||
|
||||
``` javascript
|
||||
├── main.dart //入口文件
|
||||
├── common 公共的method
|
||||
│ ├── Style.dart
|
||||
│ ├── eventBus.dart
|
||||
│ ├── provider.dart
|
||||
│ └── sql.dart
|
||||
├── components //app展示框架用到的组件
|
||||
│ ├── Input.dart
|
||||
│ ├── List.dart
|
||||
│ ├── Pagination.dart
|
||||
│ ├── Pagination2.dart
|
||||
│ ├── SearchInput.dart
|
||||
│ └── homeBanner.dart
|
||||
├── generated
|
||||
│ └── i18n.dart
|
||||
├── model //本地存放模型, 不应该加入逻辑层
|
||||
│ ├── base.dart
|
||||
│ ├── cat.dart
|
||||
│ ├── story.dart
|
||||
│ └── widget.dart
|
||||
├── routers //路由
|
||||
│ ├── application.dart
|
||||
│ ├── router_handler.dart
|
||||
│ └── routers.dart
|
||||
├── views //app展示界面
|
||||
│ ├── Detail.dart
|
||||
│ ├── FirstPage.dart
|
||||
│ ├── FourthPage.dart
|
||||
│ ├── ThirdPage.dart
|
||||
│ ├── category.dart
|
||||
│ ├── demos
|
||||
│ │ ├── home.dart
|
||||
│ │ └── layout
|
||||
│ │ ├── SamplePage.dart
|
||||
│ │ └── layout_type.dart
|
||||
│ └── widgetPage.dart
|
||||
└── widgets
|
||||
└── ... //下面详细说明
|
||||
```
|
||||
|
||||
``` javascript
|
||||
└── widgets // 对flutter所有元素和组件的分类
|
||||
├── 404.dart
|
||||
├── index.dart // widgets 的总入口文件
|
||||
├── components // 组件的分类 (区别于上面的components)
|
||||
│ └── index.dart
|
||||
├── elements // 基础元素的分类
|
||||
│ ├── index.dart // elements下的 elements 类型入口文件
|
||||
│ ├── Form // elements下的 From 类型集合
|
||||
│ │ ├── Button // button 元素,里面是 文件夹代表类名/index.dart
|
||||
│ │ │ ├── FlatButton
|
||||
│ │ │ │ └── index.dart
|
||||
│ │ │ ├── RaisedButton
|
||||
│ │ │ │ └── index.dart
|
||||
│ │ │ └── index.dart
|
||||
│ │ ├── CheckBox
|
||||
│ │ ├── Input
|
||||
│ │ ├── Radio
|
||||
│ │ ├── Slider
|
||||
│ │ ├── Switch
|
||||
│ │ ├── Text
|
||||
│ │ └── index.dart
|
||||
│ ├── Frame // elements下的 Frame 类型集合
|
||||
│ │ ├── Align
|
||||
│ │ ├── Axis
|
||||
│ │ ├── Box
|
||||
│ │ ├── Expanded
|
||||
│ │ ├── Layout
|
||||
│ │ ├── Stack
|
||||
│ │ ├── Table
|
||||
│ │ └── spacing
|
||||
│ └── Media // elements下的 Media 类型集合
|
||||
│ ├── Canvas
|
||||
│ ├── Icon
|
||||
│ └── Image
|
||||
└── themes
|
||||
└── index.dart
|
||||
```
|
||||
|
||||
```javascript
|
||||
widget 里的文件结构,用来存放封装的逻辑组件, 文件目录应为, 类比rax
|
||||
- widget // widget 下详细元素或组件的目录结构
|
||||
- hello-world // 例如
|
||||
- mods // (可选, 子模块)
|
||||
- mocks // (可选)
|
||||
- utils // (可选, 存放暂时的私有method)
|
||||
- schema
|
||||
- index.dart
|
||||
```
|
@ -13,17 +13,22 @@ class Provider {
|
||||
Future init(bool isCreate) async {
|
||||
String databasesPath = await getDatabasesPath();
|
||||
String path = join(databasesPath, 'flutter.db');
|
||||
// print("path ${path}");
|
||||
|
||||
try {
|
||||
db = await openDatabase(path);
|
||||
} catch (e) {
|
||||
print("Error $e");
|
||||
}
|
||||
if (db == null && isCreate) {
|
||||
ByteData data = await rootBundle.load(join("assets", "app.db"));
|
||||
List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
|
||||
List<int> bytes =
|
||||
data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
|
||||
await new File(path).writeAsBytes(bytes);
|
||||
|
||||
db = await openDatabase(path,version: 2,onCreate : (Database db, int version) async{
|
||||
// print('db created version is $version');
|
||||
db = await openDatabase(path, version: 2,
|
||||
onCreate: (Database db, int version) async {
|
||||
print('db created version is $version');
|
||||
}, onOpen: (Database db) async {
|
||||
// print('new db opened');
|
||||
print('new db opened');
|
||||
});
|
||||
} else {
|
||||
// print('Opening existing database');
|
||||
|
@ -28,7 +28,10 @@ class Sql extends BaseModel {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
// condition: {}
|
||||
Future<int> delete(String value,String key) async{
|
||||
return await this.db.delete(tableName,where:'$key = ?',whereArgs:[value]);
|
||||
}
|
||||
|
||||
Future<List> getByCondition({Map<dynamic, dynamic> conditions}) async {
|
||||
if (conditions == null || conditions.isEmpty) {
|
||||
return this.get();
|
||||
@ -36,12 +39,10 @@ class Sql extends BaseModel {
|
||||
String stringConditions = '';
|
||||
|
||||
int index = 0;
|
||||
// print("condition>>> $conditions");
|
||||
conditions.forEach((key, value) {
|
||||
if (value == null) {
|
||||
return ;
|
||||
}
|
||||
// print("$key value.runtimeType: ${value.runtimeType}");
|
||||
if (value.runtimeType == String) {
|
||||
stringConditions = '$stringConditions $key = "$value"';
|
||||
}
|
||||
@ -92,7 +93,6 @@ class Sql extends BaseModel {
|
||||
}
|
||||
index++;
|
||||
});
|
||||
print("this is string search condition for sql > $stringConditions");
|
||||
|
||||
return await this.query(tableName, where: stringConditions);
|
||||
}
|
||||
|
@ -5,11 +5,13 @@
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
// import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import '../routers/application.dart';
|
||||
import '../components/markdown.dart';
|
||||
import '../model/collection.dart';
|
||||
import '../widgets/index.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
|
||||
class WidgetDemo extends StatelessWidget {
|
||||
class WidgetDemo extends StatefulWidget {
|
||||
final List<dynamic> contentList;
|
||||
final String docUrl;
|
||||
final String title;
|
||||
@ -23,6 +25,27 @@ class WidgetDemo extends StatelessWidget {
|
||||
@required this.docUrl})
|
||||
: super(key: key);
|
||||
|
||||
_WidgetDemoState createState() => _WidgetDemoState();
|
||||
}
|
||||
|
||||
class _WidgetDemoState extends State<WidgetDemo> {
|
||||
bool _hasCollected = false;
|
||||
CollectionControlModel _collectionControl = new CollectionControlModel();
|
||||
Collection _collection;
|
||||
Color _collectionColor;
|
||||
List widgetDemosList = new WidgetDemoList().getDemos();
|
||||
String _router = '';
|
||||
|
||||
void showInSnackBar(String value) {
|
||||
Fluttertoast.showToast(
|
||||
msg: value,
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.CENTER,
|
||||
timeInSecForIos: 1,
|
||||
backgroundColor: Colors.grey,
|
||||
textColor: Colors.white);
|
||||
}
|
||||
|
||||
void _launchURL(String url) async {
|
||||
if (await canLaunch(url)) {
|
||||
await launch(url);
|
||||
@ -37,7 +60,7 @@ class WidgetDemo extends StatelessWidget {
|
||||
height: 10.0,
|
||||
),
|
||||
];
|
||||
contentList.forEach((item) {
|
||||
widget.contentList.forEach((item) {
|
||||
if (item.runtimeType == String) {
|
||||
_list.add(MarkdownBody(item));
|
||||
_list.add(
|
||||
@ -52,24 +75,72 @@ class WidgetDemo extends StatelessWidget {
|
||||
return _list;
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_collectionControl.getRouterByName(widget.title).then((list) {
|
||||
widgetDemosList.forEach((item) {
|
||||
if (item.name == widget.title) {
|
||||
_router = item.routerName;
|
||||
}
|
||||
});
|
||||
setState(() {
|
||||
_hasCollected = list.length > 0;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 点击收藏按钮
|
||||
_getCollection() {
|
||||
if (_hasCollected) {
|
||||
// 删除操作
|
||||
_collectionControl.deleteByName(widget.title).then((result) {
|
||||
if (result > 0 && this.mounted) {
|
||||
setState(() {
|
||||
_hasCollected = false;
|
||||
});
|
||||
showInSnackBar('已取消收藏');
|
||||
return;
|
||||
}
|
||||
print('删除错误');
|
||||
});
|
||||
} else {
|
||||
// 插入操作
|
||||
_collectionControl
|
||||
.insert(Collection(name: widget.title, router: _router))
|
||||
.then((result) {
|
||||
if (this.mounted) {
|
||||
setState(() {
|
||||
_hasCollected = true;
|
||||
});
|
||||
showInSnackBar('收藏成功');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (_hasCollected) {
|
||||
_collectionColor = Colors.yellow;
|
||||
} else {
|
||||
_collectionColor = Colors.white;
|
||||
}
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(title),
|
||||
title: Text(widget.title),
|
||||
actions: <Widget>[
|
||||
new IconButton(
|
||||
tooltip: 'widget doc',
|
||||
onPressed: () {
|
||||
_launchURL(docUrl);
|
||||
_launchURL(widget.docUrl);
|
||||
},
|
||||
icon: Icon(Icons.library_books),
|
||||
),
|
||||
new IconButton(
|
||||
tooltip: 'github code',
|
||||
onPressed: () {
|
||||
print(Application.github['widgetsURL']+codeUrl);
|
||||
_launchURL(Application.github['widgetsURL']+codeUrl);
|
||||
_launchURL(Application.github['widgetsURL'] + widget.codeUrl);
|
||||
},
|
||||
icon: Icon(Icons.code),
|
||||
),
|
||||
@ -94,6 +165,15 @@ class WidgetDemo extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: _getCollection,
|
||||
tooltip: '收藏',
|
||||
child: Icon(
|
||||
Icons.star,
|
||||
color: _collectionColor,
|
||||
),
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_rookie_book/views/Detail.dart';
|
||||
|
||||
class List extends StatefulWidget {
|
||||
class CompList extends StatefulWidget {
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
// TODO: implement createState
|
||||
@ -9,7 +9,7 @@ class List extends StatefulWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class ListState extends State<List> {
|
||||
class ListState extends State<CompList> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
/// getData() ; this is test;
|
@ -1,26 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Input extends StatelessWidget {
|
||||
Input({Key key, this.active}):super(key: key);
|
||||
|
||||
String active;
|
||||
TextEditingController controller;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Column(
|
||||
children: <Widget>[
|
||||
new Container(
|
||||
padding: new EdgeInsets.only(top:100.0),
|
||||
child: new Text('这是一个组件')
|
||||
),
|
||||
new Container(
|
||||
decoration: new BoxDecoration(border: new Border.all(width:1.0,color: Colors.blue)),
|
||||
padding: new EdgeInsets.all(20.0),
|
||||
child: new Text('来自输入框:'+active)
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
}
|
178
lib/components/ListRefresh.dart
Normal file
178
lib/components/ListRefresh.dart
Normal file
@ -0,0 +1,178 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 一晟
|
||||
* Date: 2019/1/4
|
||||
* Time: 上午1:16
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: FlatButton 的示例
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
import 'dart:math';
|
||||
|
||||
|
||||
class ListRefresh extends StatefulWidget {
|
||||
final renderItem;
|
||||
final requestApi;
|
||||
|
||||
const ListRefresh([this.requestApi,this.renderItem]) : super();
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => listRefresh();
|
||||
}
|
||||
|
||||
class listRefresh extends State<ListRefresh> {
|
||||
bool isLoading = false; // 是否正在请求数据中
|
||||
bool _hasMore = true; // 是否还有更多数据可加载
|
||||
int _pageIndex = 0; // 页面的索引
|
||||
int _pageTotal = 0; // 页面的索引
|
||||
List items = new List();
|
||||
ScrollController _scrollController = new ScrollController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_getMoreData();
|
||||
_scrollController.addListener(() {
|
||||
// 如果下拉的当前位置到scroll的最下面
|
||||
if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
|
||||
_getMoreData();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* 回弹效果
|
||||
* */
|
||||
backElasticEffect(){
|
||||
// double edge = 50.0;
|
||||
// double offsetFromBottom = _scrollController.position.maxScrollExtent - _scrollController.position.pixels;
|
||||
// if (offsetFromBottom < edge) { // 添加一个动画没有更多数据的时候 ListView 向下移动覆盖正在加载更多数据的标志
|
||||
// _scrollController.animateTo(
|
||||
// _scrollController.offset - (edge -offsetFromBottom),
|
||||
// duration: new Duration(milliseconds: 1000),
|
||||
// curve: Curves.easeOut);
|
||||
// }
|
||||
}
|
||||
|
||||
/*
|
||||
* list探底,执行的具体事件
|
||||
* */
|
||||
Future _getMoreData() async {
|
||||
if (!isLoading && _hasMore) { // 如果上一次异步请求数据完成 同时有数据可以加载
|
||||
setState(() => isLoading = true);
|
||||
//if(_hasMore){ // 还有数据可以拉新
|
||||
List newEntries = await mokeHttpRequest();
|
||||
//if (newEntries.isEmpty) {
|
||||
_hasMore = (_pageIndex <= _pageTotal);
|
||||
setState(() {
|
||||
items.addAll(newEntries);
|
||||
isLoading = false;
|
||||
});
|
||||
backElasticEffect();
|
||||
}else if (!isLoading && !_hasMore){ // 这样判断,减少以后的绘制
|
||||
_pageIndex = 0;
|
||||
backElasticEffect();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 伪装吐出新数据
|
||||
* */
|
||||
Future<List> mokeHttpRequest() async {
|
||||
if(widget.requestApi is Function){
|
||||
final listObj = await widget.requestApi({'pageIndex':_pageIndex});
|
||||
_pageIndex = listObj['pageIndex'];
|
||||
_pageTotal = listObj['total'];
|
||||
return listObj['list'];
|
||||
}else {
|
||||
return Future.delayed(Duration(seconds: 2), () {
|
||||
return [];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 下拉加载的事件,清空之前list内容,取前X个
|
||||
* 其实就是列表重置
|
||||
* */
|
||||
Future<Null> _handleRefresh() async {
|
||||
List newEntries = await mokeHttpRequest();
|
||||
setState(() {
|
||||
items.clear();
|
||||
items.addAll(newEntries);
|
||||
isLoading = false;
|
||||
_hasMore = true;
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* 加载中的提示
|
||||
* */
|
||||
Widget _buildLoadText() {
|
||||
return Container(child: Padding(
|
||||
padding: const EdgeInsets.all(18.0),
|
||||
child: Center(
|
||||
child: Text("数据没有更多了!!!"),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
/*
|
||||
* 上提加载loading的widget,如果数据到达极限,显示没有更多
|
||||
* */
|
||||
Widget _buildProgressIndicator() {
|
||||
if(_hasMore){
|
||||
return new Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: new Center(
|
||||
child:Column(
|
||||
children: <Widget>[
|
||||
new Opacity(
|
||||
opacity: isLoading ? 1.0 : 0.0,
|
||||
child: new CircularProgressIndicator(valueColor: AlwaysStoppedAnimation(Colors.blue)),
|
||||
),
|
||||
SizedBox(height:20.0),
|
||||
Text('稍等片刻更精彩...',style: TextStyle(fontSize: 14.0),)
|
||||
],)
|
||||
//child:
|
||||
),
|
||||
);
|
||||
}else {
|
||||
return _buildLoadText();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
_scrollController.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new RefreshIndicator(
|
||||
child:ListView.builder(
|
||||
itemCount: items.length + 1,
|
||||
itemBuilder: (context, index) {
|
||||
if(index == 0 && index != items.length){
|
||||
return Container(height:0);
|
||||
}
|
||||
if (index == items.length) {
|
||||
//return _buildLoadText();
|
||||
return _buildProgressIndicator();
|
||||
} else {
|
||||
//print('itemsitemsitemsitems:${items[index].title}');
|
||||
//return ListTile(title: Text("Index${index}:${items[index].title}"));
|
||||
if (widget.renderItem is Function) {
|
||||
return widget.renderItem(index,items[index]);
|
||||
}
|
||||
//return makeCard(index,items[index]);
|
||||
}
|
||||
},
|
||||
controller: _scrollController,
|
||||
),
|
||||
onRefresh: _handleRefresh,
|
||||
);
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import './homeBanner.dart';
|
||||
import '../model/story.dart';
|
||||
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class Pagination extends StatelessWidget {
|
||||
static const String routeName = '/material/page-selector';
|
||||
@ -21,36 +21,31 @@ class Pagination extends StatelessWidget {
|
||||
List<StoryModel> bannerStories = [];
|
||||
|
||||
List<dynamic> arr = [
|
||||
{'image': 'https://pic2.zhimg.com/v2-6733af287e1220a041fc8dcef6be9dc9.jpg', 'type': 0, 'id': 9695909, 'ga_prefix': 091507, 'title': '从一个摄影师的角度,我来谈谈这一代 iPhone 是如何继续'},
|
||||
{'image': 'https://pic1.zhimg.com/v2-c9a673ff89e5cc4c31ffcdf0c2d2f364.jpg', 'type': 0, 'id': 9695859, 'ga_prefix': 091517, 'title': '怪不得他能拿诺贝尔文学奖,一个月就能写出一部了不起的长篇小说'},
|
||||
{'image': 'https://pic3.zhimg.com/v2-cf89ac60dbe59ab3ca908ff4bbf843e6.jpg', 'type': 0, 'id': 96956491409, 'title': '「死者被碎尸,警方排除他杀」,这并不荒唐'},
|
||||
{'image': 'https://pic4.zhimg.com/v2-e21659cb7bc4ab43599772fa552e6e8b.jpg', 'type': 0, 'id': 9695816, 'ga_prefix': 091312, 'title': 'iPhone 5c、SE 接连失利之后,这次苹果还是「没长记性」'}
|
||||
{'image': 'https://img.alicdn.com/tfs/TB1W4hMAwHqK1RjSZJnXXbNLpXa-519-260.jpg', 'type': 0, 'id': 9695909, 'url': 'https://www.zhihu.com/question/294145797/answer/551162834', 'title': '为什么阿里巴巴、腾讯和 Google 之类的企业都在使用 Flutter 开发 App?'},
|
||||
{'image': 'https://img.alicdn.com/tfs/TB1XmFIApzqK1RjSZSgXXcpAVXa-720-338.jpg', 'type': 0, 'id': 9695859, 'url': 'https://zhuanlan.zhihu.com/p/51696594', 'title': 'Flutter 1.0 正式发布: Google 的便携 UI 工具包'},
|
||||
{'image': 'https://img.alicdn.com/tfs/TB1mClCABLoK1RjSZFuXXXn0XXa-600-362.jpg', 'type': 0, 'id': 96956491409, 'url':'https://zhuanlan.zhihu.com/p/53497167','title': 'Flutter 示范应用现已开源 — 万物起源(The History of Everything)'},
|
||||
{'image': 'https://img.alicdn.com/tfs/TB1fXxIAAvoK1RjSZFNXXcxMVXa-600-362.jpg', 'type': 0, 'id': 9695816, 'url': 'https://mp.weixin.qq.com/s?__biz=MzAwODY4OTk2Mg==&mid=2652048101&idx=1&sn=20296088e4bd8ca33c5c9991167d9f7d&chksm=808caaa0b7fb23b65c0e5806209f8d86da6732f3a00a70353f3606018339518b0a8656f14dc5&mpshare=1&scene=2&srcid=0106SZapVysZdIS6Oc5AhNH6&from=timeline&ascene=2&devicetype=android-27&version=27000038&nettype=WIFI&abtest_cookie=BQABAAgACgALABMAFAAFAJ2GHgAjlx4AV5keAJuZHgCcmR4AAAA%3D&lang=zh_CN&pass_ticket=4K1%2FUpsxP4suPj2iubR17wbAP7r9LW9iYrPAC2dppTqv7j7JO5FWMXtcKeBRxueV&wx_header=1', 'title': 'Flutter 与 Material Design 双剑合璧,助您构建精美应用'}
|
||||
];
|
||||
|
||||
|
||||
// @override
|
||||
// void initState() { // 无状态widget 不会调用
|
||||
// print('start');
|
||||
// /// super.initState();
|
||||
// arr.forEach((item) {
|
||||
// bannerStories.add(StoryModel.fromJson(item));
|
||||
// });
|
||||
//
|
||||
// }
|
||||
|
||||
void _launchURL(String url) async {
|
||||
if (await canLaunch(url)) {
|
||||
await launch(url);
|
||||
} else {
|
||||
throw 'Could not launch $url';
|
||||
}
|
||||
}
|
||||
|
||||
List<Widget> _PageSelector(BuildContext context) {
|
||||
List<Widget> list = [];
|
||||
print('start');
|
||||
/// super.initState();
|
||||
arr.forEach((item) {
|
||||
bannerStories.add(StoryModel.fromJson(item));
|
||||
});
|
||||
|
||||
|
||||
if (icons.length > 0) {
|
||||
if (arr.length > 0) {
|
||||
list.add(HomeBanner(bannerStories, (story) {
|
||||
/// _openStoryDetailPage(story);
|
||||
_launchURL('${story.url}');
|
||||
}));
|
||||
}
|
||||
return list;
|
||||
|
@ -1,112 +0,0 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class _PageSelector extends StatelessWidget {
|
||||
const _PageSelector({ this.icons });
|
||||
|
||||
final List<Icon> icons;
|
||||
|
||||
void _handleArrowButtonPress(BuildContext context, int delta) {
|
||||
final TabController controller = DefaultTabController.of(context);
|
||||
if (!controller.indexIsChanging)
|
||||
controller.animateTo((controller.index + delta).clamp(0, icons.length - 1));
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final TabController controller = DefaultTabController.of(context);
|
||||
final Color color = Theme.of(context).accentColor;
|
||||
return new SafeArea(
|
||||
top: false,
|
||||
bottom: false,
|
||||
child: new Column(
|
||||
children: <Widget>[
|
||||
new Expanded(
|
||||
child: new IconTheme(
|
||||
data: new IconThemeData(
|
||||
size: 128.0,
|
||||
color: color,
|
||||
),
|
||||
child: new TabBarView(
|
||||
children: icons.map((Icon icon) {
|
||||
return
|
||||
new Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child:new Container(
|
||||
color: Colors.red,
|
||||
width:300.0,
|
||||
height:250.0,
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: new Card(
|
||||
color: Colors.yellow,
|
||||
child: new Center(
|
||||
child: icon,
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
}).toList()
|
||||
|
||||
),
|
||||
),
|
||||
),
|
||||
new Container(
|
||||
margin: const EdgeInsets.only(top: 16.0),
|
||||
child: new Row(
|
||||
children: <Widget>[
|
||||
new IconButton(
|
||||
icon: const Icon(Icons.chevron_left),
|
||||
color: color,
|
||||
onPressed: () { _handleArrowButtonPress(context, -1); },
|
||||
tooltip: 'Page back'
|
||||
),
|
||||
new TabPageSelector(controller: controller),
|
||||
new IconButton(
|
||||
icon: const Icon(Icons.chevron_right),
|
||||
color: color,
|
||||
onPressed: () { _handleArrowButtonPress(context, 1); },
|
||||
tooltip: 'Page forward'
|
||||
)
|
||||
],
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class Pagination2 extends StatelessWidget {
|
||||
static const String routeName = '/material/page-selector';
|
||||
static final List<Icon> icons = <Icon>[
|
||||
const Icon(Icons.event, semanticLabel: 'Event'),
|
||||
const Icon(Icons.home, semanticLabel: 'Home'),
|
||||
const Icon(Icons.android, semanticLabel: 'Android'),
|
||||
const Icon(Icons.alarm, semanticLabel: 'Alarm'),
|
||||
const Icon(Icons.face, semanticLabel: 'Face'),
|
||||
const Icon(Icons.language, semanticLabel: 'Language'),
|
||||
];
|
||||
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// return new Scaffold(
|
||||
// appBar: new AppBar(title: const Text('Page selector')),
|
||||
// body: new DefaultTabController(
|
||||
// length: icons.length,
|
||||
// child: new _PageSelector(icons: icons),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new DefaultTabController(
|
||||
length: icons.length,
|
||||
child: new _PageSelector(icons: icons),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import '../common/Style.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
typedef String FormFieldFormatter<T>(T v);
|
||||
@ -16,22 +15,29 @@ class MaterialSearchResult<T> extends StatelessWidget {
|
||||
this.value,
|
||||
this.text,
|
||||
this.icon,
|
||||
this.onTap
|
||||
}) : super(key: key);
|
||||
|
||||
final T value;
|
||||
final VoidCallback onTap;
|
||||
final String text;
|
||||
final IconData icon;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Container(
|
||||
return new InkWell(
|
||||
onTap: this.onTap,
|
||||
child: new Container(
|
||||
height: 64.0,
|
||||
padding: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 10.0),
|
||||
child: new Row(
|
||||
children: <Widget>[
|
||||
new Container(width: 30.0, child: new Icon(icon)),
|
||||
new Container(width: 30.0, child: new Icon(icon)) ?? null,
|
||||
new Expanded(child: new Text(text, style: Theme.of(context).textTheme.subhead)),
|
||||
new Text(text, style: Theme.of(context).textTheme.subhead)
|
||||
],
|
||||
),
|
||||
height: 64.0,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -51,9 +57,10 @@ class MaterialSearch<T> extends StatefulWidget {
|
||||
this.iconColor = Colors.black,
|
||||
this.leading,
|
||||
}) : assert(() {
|
||||
if (results == null && getResults == null
|
||||
|| results != null && getResults != null) {
|
||||
throw new AssertionError('Either provide a function to get the results, or the results.');
|
||||
if (results == null && getResults == null ||
|
||||
results != null && getResults != null) {
|
||||
throw new AssertionError(
|
||||
'Either provide a function to get the results, or the results.');
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -85,7 +92,10 @@ class _MaterialSearchState<T> extends State<MaterialSearch> {
|
||||
TextEditingController _controller = new TextEditingController();
|
||||
|
||||
_filter(dynamic v, String c) {
|
||||
return v.toString().toLowerCase().trim()
|
||||
return v
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.contains(new RegExp(r'' + c.toLowerCase().trim() + ''));
|
||||
}
|
||||
|
||||
@ -149,11 +159,30 @@ class _MaterialSearchState<T> extends State<MaterialSearch> {
|
||||
super.dispose();
|
||||
_resultsTimer?.cancel();
|
||||
}
|
||||
Widget buildBody(List results) {
|
||||
if (_loading) {
|
||||
return new Center(
|
||||
child: new Padding(
|
||||
padding: const EdgeInsets.only(top: 50.0),
|
||||
child: new CircularProgressIndicator()
|
||||
)
|
||||
);
|
||||
}
|
||||
if (results.isNotEmpty) {
|
||||
var content = new SingleChildScrollView(
|
||||
child: new Column(
|
||||
children: results
|
||||
)
|
||||
);
|
||||
return content;
|
||||
}
|
||||
return Center(child: Text("暂无数据"));
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var results = (widget.results ?? _results)
|
||||
.where((MaterialSearchResult result) {
|
||||
var results =
|
||||
(widget.results ?? _results).where((MaterialSearchResult result) {
|
||||
if (widget.filter != null) {
|
||||
return widget.filter(result.value, _criteria);
|
||||
}
|
||||
@ -164,18 +193,16 @@ class _MaterialSearchState<T> extends State<MaterialSearch> {
|
||||
}
|
||||
|
||||
return true;
|
||||
})
|
||||
.toList();
|
||||
}).toList();
|
||||
|
||||
if (widget.sort != null) {
|
||||
results.sort((a, b) => widget.sort(a.value, b.value, _criteria));
|
||||
}
|
||||
|
||||
results = results
|
||||
.take(widget.limit)
|
||||
.toList();
|
||||
results = results.take(widget.limit).toList();
|
||||
|
||||
IconThemeData iconTheme = Theme.of(context).iconTheme.copyWith(color: widget.iconColor);
|
||||
IconThemeData iconTheme =
|
||||
Theme.of(context).iconTheme.copyWith(color: widget.iconColor);
|
||||
|
||||
return new Scaffold(
|
||||
appBar: new AppBar(
|
||||
@ -185,7 +212,8 @@ class _MaterialSearchState<T> extends State<MaterialSearch> {
|
||||
title: new TextField(
|
||||
controller: _controller,
|
||||
autofocus: true,
|
||||
decoration: new InputDecoration.collapsed(hintText: widget.placeholder),
|
||||
decoration:
|
||||
new InputDecoration.collapsed(hintText: widget.placeholder),
|
||||
style: Theme.of(context).textTheme.title,
|
||||
onSubmitted: (String value) {
|
||||
if (widget.onSubmit != null) {
|
||||
@ -193,34 +221,19 @@ class _MaterialSearchState<T> extends State<MaterialSearch> {
|
||||
}
|
||||
},
|
||||
),
|
||||
actions: _criteria.length == 0 ? [] : [
|
||||
actions: _criteria.length == 0
|
||||
? []
|
||||
: [
|
||||
new IconButton(
|
||||
icon: new Icon(Icons.clear),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_controller.text = _criteria = '';
|
||||
});
|
||||
}
|
||||
),
|
||||
}),
|
||||
],
|
||||
),
|
||||
body: _loading
|
||||
? new Center(
|
||||
child: new Padding(
|
||||
padding: const EdgeInsets.only(top: 50.0),
|
||||
child: new CircularProgressIndicator()
|
||||
),
|
||||
)
|
||||
: new SingleChildScrollView(
|
||||
child: new Column(
|
||||
children: results.map((MaterialSearchResult result) {
|
||||
return new InkWell(
|
||||
onTap: () => widget.onSelect(result.value),
|
||||
child: result,
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
body: buildBody(results),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -232,7 +245,11 @@ class _MaterialSearchPageRoute<T> extends MaterialPageRoute<T> {
|
||||
maintainState: true,
|
||||
bool fullscreenDialog: false,
|
||||
}) : assert(builder != null),
|
||||
super(builder: builder, settings: settings, maintainState: maintainState, fullscreenDialog: fullscreenDialog);
|
||||
super(
|
||||
builder: builder,
|
||||
settings: settings,
|
||||
maintainState: maintainState,
|
||||
fullscreenDialog: fullscreenDialog);
|
||||
}
|
||||
|
||||
class MaterialSearchInput<T> extends StatefulWidget {
|
||||
@ -263,11 +280,13 @@ class MaterialSearchInput<T> extends StatefulWidget {
|
||||
final ValueChanged<T> onSelect;
|
||||
|
||||
@override
|
||||
_MaterialSearchInputState<T> createState() => new _MaterialSearchInputState<T>();
|
||||
_MaterialSearchInputState<T> createState() =>
|
||||
new _MaterialSearchInputState<T>();
|
||||
}
|
||||
|
||||
class _MaterialSearchInputState<T> extends State<MaterialSearchInput<T>> {
|
||||
GlobalKey<FormFieldState<T>> _formFieldKey = new GlobalKey<FormFieldState<T>>();
|
||||
GlobalKey<FormFieldState<T>> _formFieldKey =
|
||||
new GlobalKey<FormFieldState<T>>();
|
||||
|
||||
_buildMaterialSearchPage(BuildContext context) {
|
||||
return new _MaterialSearchPageRoute<T>(
|
||||
@ -286,8 +305,7 @@ class _MaterialSearchInputState<T> extends State<MaterialSearchInput<T>> {
|
||||
onSelect: (dynamic value) => Navigator.of(context).pop(value),
|
||||
),
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
_showMaterialSearch(BuildContext context) {
|
||||
@ -302,7 +320,9 @@ class _MaterialSearchInputState<T> extends State<MaterialSearchInput<T>> {
|
||||
}
|
||||
|
||||
bool get autovalidate {
|
||||
return widget.autovalidate ?? Form.of(context)?.widget?.autovalidate ?? false;
|
||||
return widget.autovalidate ??
|
||||
Form.of(context)?.widget?.autovalidate ??
|
||||
false;
|
||||
}
|
||||
|
||||
bool _isEmpty(field) {
|
||||
@ -324,14 +344,16 @@ class _MaterialSearchInputState<T> extends State<MaterialSearchInput<T>> {
|
||||
isEmpty: _isEmpty(field),
|
||||
decoration: new InputDecoration(
|
||||
labelText: widget.placeholder,
|
||||
border: InputBorder.none,
|
||||
errorText: field.errorText,
|
||||
),
|
||||
child: _isEmpty(field) ? null : new Text(
|
||||
child: _isEmpty(field)
|
||||
? null
|
||||
: new Text(
|
||||
widget.formatter != null
|
||||
? widget.formatter(field.value)
|
||||
: field.value.toString(),
|
||||
style: valueStyle
|
||||
),
|
||||
style: valueStyle),
|
||||
);
|
||||
},
|
||||
),
|
||||
@ -352,17 +374,22 @@ class SearchInput extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Container(
|
||||
height: 40.0,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).backgroundColor,
|
||||
borderRadius: BorderRadius.circular(4.0)),
|
||||
child: new Row(
|
||||
children: <Widget>[
|
||||
new Padding(
|
||||
padding: new EdgeInsets.only(right: 10.0, top: 3.0),
|
||||
child: new Icon(Icons.search, size: 24.0, color: Theme.of(context).primaryColorDark),
|
||||
padding: new EdgeInsets.only(right: 10.0, top: 3.0, left: 10.0),
|
||||
child: new Icon(Icons.search,
|
||||
size: 24.0, color: Theme.of(context).accentColor),
|
||||
),
|
||||
new Expanded(
|
||||
child: new MaterialSearchInput(
|
||||
placeholder: '搜索 flutter 组件',
|
||||
getResults: getResults,
|
||||
)
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -101,7 +101,7 @@ class _BannerState extends State<HomeBanner> {
|
||||
child: Container(
|
||||
margin: EdgeInsets.symmetric(vertical: 22.0, horizontal: 16.0),
|
||||
child: Text(
|
||||
title, style: TextStyle(color: Colors.white, fontSize: 22.0),),),
|
||||
title, style: TextStyle(color: Colors.white, fontSize: 18.0),),),
|
||||
);
|
||||
}
|
||||
|
||||
|
32
lib/components/markdown.dart
Normal file
32
lib/components/markdown.dart
Normal file
@ -0,0 +1,32 @@
|
||||
import 'package:flutter_markdown/flutter_markdown.dart' as md;
|
||||
import '../common/high_light_code.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// 使用方法
|
||||
/// MarkdownBody(markdown)
|
||||
final hightlighter = new HighLight();
|
||||
class HighLight extends md.SyntaxHighlighter {
|
||||
@override
|
||||
TextSpan format(String source) {
|
||||
// TODO: implement format
|
||||
final SyntaxHighlighterStyle style = SyntaxHighlighterStyle.lightThemeStyle();
|
||||
return TextSpan(
|
||||
style: const TextStyle(fontSize: 10.0),
|
||||
children: <TextSpan>[
|
||||
DartSyntaxHighlighter(style).format(source)
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
class MarkdownBody extends StatelessWidget {
|
||||
String data;
|
||||
MarkdownBody(this.data);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// TODO: implement build
|
||||
return md.MarkdownBody(data: data, syntaxHighlighter: new HighLight());
|
||||
}
|
||||
}
|
88
lib/components/widget_item.dart
Normal file
88
lib/components/widget_item.dart
Normal file
@ -0,0 +1,88 @@
|
||||
/**
|
||||
* @author 一凨
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
import '../common/Style.dart';
|
||||
import '../common/widget_name_to_icon.dart';
|
||||
|
||||
class WidgetItem extends StatelessWidget {
|
||||
final String title;
|
||||
final VoidCallback onTap;
|
||||
final int index; //用于计算border
|
||||
final int totalCount;
|
||||
final int rowLength;
|
||||
String _widgetName;
|
||||
|
||||
WidgetItem(
|
||||
{this.title, this.onTap, this.index, this.totalCount, this.rowLength});
|
||||
|
||||
Border _buildBorder(context) {
|
||||
Border _border;
|
||||
bool isRight = (index % rowLength) == (rowLength - 1); //是不是最右边的,决定是否有右侧边框
|
||||
var currentRow = (index + 1) % rowLength > 0
|
||||
? (index + 1) ~/ rowLength + 1
|
||||
: (index + 1) ~/ rowLength;
|
||||
int totalRow = totalCount % rowLength > 0
|
||||
? totalCount ~/ rowLength + 1
|
||||
: totalCount ~/ rowLength;
|
||||
if (currentRow < totalRow && isRight) {
|
||||
//不是最后一行,是最右边
|
||||
_border = Border(
|
||||
bottom: const BorderSide(
|
||||
width: 1.0, color: Color(WidgetDemoColor.borderColor)),
|
||||
);
|
||||
}
|
||||
if (currentRow < totalRow && !isRight) {
|
||||
_border = Border(
|
||||
right: const BorderSide(
|
||||
width: 1.0, color: Color(WidgetDemoColor.borderColor)),
|
||||
bottom: const BorderSide(
|
||||
width: 1.0, color: Color(WidgetDemoColor.borderColor)),
|
||||
);
|
||||
}
|
||||
if (currentRow == totalRow && !isRight) {
|
||||
_border = Border(
|
||||
right: const BorderSide(
|
||||
width: 1.0, color: Color(WidgetDemoColor.borderColor)),
|
||||
);
|
||||
}
|
||||
return _border;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
_widgetName = title.replaceFirst(
|
||||
//首字母转为大写
|
||||
title.substring(0, 1),
|
||||
title.substring(0, 1).toUpperCase());
|
||||
Icon widgetIcon;
|
||||
if (WidgetName2Icon.icons[_widgetName] != null) {
|
||||
widgetIcon = Icon(WidgetName2Icon.icons[_widgetName]);
|
||||
} else {
|
||||
widgetIcon = Icon(
|
||||
Icons.crop,
|
||||
);
|
||||
}
|
||||
return InkWell(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
decoration: new BoxDecoration(
|
||||
border: _buildBorder(context),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(vertical: 30.0, horizontal: 10.0),
|
||||
height: 150.0,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: <Widget>[
|
||||
widgetIcon,
|
||||
SizedBox(
|
||||
height: 8.0,
|
||||
),
|
||||
Text(_widgetName),
|
||||
],
|
||||
) ,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
80
lib/components/widget_item_container.dart
Normal file
80
lib/components/widget_item_container.dart
Normal file
@ -0,0 +1,80 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import './widget_item.dart';
|
||||
import '../routers/application.dart';
|
||||
import '../widgets/index.dart';
|
||||
|
||||
class WidgetItemContainer extends StatelessWidget {
|
||||
final int columnCount; //一行几个
|
||||
final List<dynamic> categories;
|
||||
final bool isWidgetPoint;
|
||||
// 所有的可用demos;
|
||||
List widgetDemosList = new WidgetDemoList().getDemos();
|
||||
|
||||
WidgetItemContainer(
|
||||
{Key key,
|
||||
@required this.categories,
|
||||
@required this.columnCount,
|
||||
@required this.isWidgetPoint})
|
||||
: super(key: key);
|
||||
|
||||
List<Widget> _buildColumns(context) {
|
||||
List<Widget> _listWidget = [];
|
||||
List<Widget> _listRows = [];
|
||||
int addI;
|
||||
for (int i = 0, length = categories.length; i < length; i += columnCount) {
|
||||
_listRows = [];
|
||||
for (int innerI = 0; innerI < columnCount; innerI++) {
|
||||
addI = innerI + i;
|
||||
if (addI < length) {
|
||||
dynamic item = categories[addI];
|
||||
_listRows.add(
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: WidgetItem(
|
||||
title: item.name,
|
||||
onTap: () {
|
||||
if (isWidgetPoint) {
|
||||
String targetName = item.name;
|
||||
String targetRouter = '/category/error/404';
|
||||
widgetDemosList.forEach((item) {
|
||||
if (item.name == targetName) {
|
||||
targetRouter = item.routerName;
|
||||
}
|
||||
});
|
||||
Application.router.navigateTo(context, "${targetRouter}");
|
||||
} else {
|
||||
Application.router
|
||||
.navigateTo(context, "/category/${item.name}");
|
||||
}
|
||||
},
|
||||
index: addI,
|
||||
totalCount: length,
|
||||
rowLength: columnCount,
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
_listRows.add(
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Container(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
_listWidget.add(
|
||||
Row(
|
||||
children: _listRows,
|
||||
),
|
||||
);
|
||||
}
|
||||
return _listWidget;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: _buildColumns(context),
|
||||
);
|
||||
}
|
||||
}
|
100
lib/main.dart
100
lib/main.dart
@ -6,12 +6,15 @@ import 'views/FirstPage.dart';
|
||||
import 'views/widgetPage.dart';
|
||||
import 'views/ThirdPage.dart';
|
||||
import 'views/FourthPage.dart';
|
||||
import 'views/collection_page.dart';
|
||||
import 'routers/routers.dart';
|
||||
import 'routers/application.dart';
|
||||
import 'common/provider.dart';
|
||||
import 'model/widget.dart';
|
||||
import './widgets/index.dart';
|
||||
import 'package:flutter_rookie_book/components/SearchInput.dart';
|
||||
import 'common/Style.dart';
|
||||
|
||||
const int ThemeColor = 0xFFC91B3A;
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
MyApp() {
|
||||
@ -25,7 +28,17 @@ class MyApp extends StatelessWidget {
|
||||
return new MaterialApp(
|
||||
title: 'title',
|
||||
theme: new ThemeData(
|
||||
primarySwatch: Colors.blue,
|
||||
primaryColor: Color(ThemeColor),
|
||||
backgroundColor: Color(0xFFEFEFEF),
|
||||
accentColor: Color(0xFF888888),
|
||||
textTheme: TextTheme(
|
||||
//设置Material的默认字体样式
|
||||
body1: TextStyle(color: Color(0xFF888888), fontSize: 16.0),
|
||||
),
|
||||
iconTheme: IconThemeData(
|
||||
color: Color(ThemeColor),
|
||||
size: 35.0,
|
||||
),
|
||||
),
|
||||
home: new MyHomePage(),
|
||||
onGenerateRoute: Application.router.generator,
|
||||
@ -36,7 +49,6 @@ class MyApp extends StatelessWidget {
|
||||
var db;
|
||||
|
||||
void main() async {
|
||||
|
||||
final provider = new Provider();
|
||||
await provider.init(true);
|
||||
db = Provider.db;
|
||||
@ -52,6 +64,7 @@ class MyHomePage extends StatefulWidget {
|
||||
|
||||
class _MyHomePageState extends State<MyHomePage>
|
||||
with SingleTickerProviderStateMixin {
|
||||
WidgetControlModel widgetControl = new WidgetControlModel();
|
||||
TabController controller;
|
||||
bool isSearch = false;
|
||||
String data = '无';
|
||||
@ -60,7 +73,7 @@ class _MyHomePageState extends State<MyHomePage>
|
||||
static List tabData = [
|
||||
{'text': '业界动态', 'icon': new Icon(Icons.language)},
|
||||
{'text': 'WIDGET', 'icon': new Icon(Icons.extension)},
|
||||
{'text': '官网地址', 'icon': new Icon(Icons.home)},
|
||||
{'text': '组件收藏', 'icon': new Icon(Icons.star)},
|
||||
{'text': '关于手册', 'icon': new Icon(Icons.favorite)}
|
||||
];
|
||||
|
||||
@ -80,6 +93,7 @@ class _MyHomePageState extends State<MyHomePage>
|
||||
_onTabChange();
|
||||
}
|
||||
});
|
||||
Application.controller = controller;
|
||||
}
|
||||
|
||||
@override
|
||||
@ -87,64 +101,94 @@ class _MyHomePageState extends State<MyHomePage>
|
||||
controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
Widget buildSearchInput(){
|
||||
|
||||
void onWidgetTap(WidgetPoint widgetPoint, BuildContext context) {
|
||||
List widgetDemosList = new WidgetDemoList().getDemos();
|
||||
String targetName = widgetPoint.name;
|
||||
String targetRouter = '/category/error/404';
|
||||
widgetDemosList.forEach((item) {
|
||||
if (item.name == targetName) {
|
||||
targetRouter = item.routerName;
|
||||
}
|
||||
});
|
||||
Application.router.navigateTo(context, "${targetRouter}");
|
||||
}
|
||||
|
||||
Widget buildSearchInput(BuildContext context) {
|
||||
return new SearchInput((value) async {
|
||||
if (value != '') {
|
||||
List<WidgetPoint> list = await widgetControl.search(value);
|
||||
|
||||
return list
|
||||
.map((item) => new MaterialSearchResult<String>(
|
||||
value: item.name,
|
||||
text: item.name,
|
||||
onTap: () {
|
||||
onWidgetTap(item, context);
|
||||
},
|
||||
))
|
||||
.toList();
|
||||
} else {
|
||||
return null;
|
||||
// if(value != ''){
|
||||
// widgetModel = new WidgetModel(db);
|
||||
// List<Map> list = await widgetModel.search(value);
|
||||
// print('list $list');
|
||||
// return list.map((item) => new MaterialSearchResult<String>(
|
||||
// value: item['name'],
|
||||
// text: item['name'] + ' ' + item['cnName'],
|
||||
// )).toList();
|
||||
// }else{
|
||||
// return null;
|
||||
// }
|
||||
|
||||
},(value){},(){});
|
||||
|
||||
}
|
||||
}, (value) {
|
||||
}, () {});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Scaffold(
|
||||
appBar: new AppBar(
|
||||
// backgroundColor: new Color(AppColor.white),
|
||||
title: buildSearchInput()),
|
||||
appBar: new AppBar(title: buildSearchInput(context)),
|
||||
body: new TabBarView(controller: controller, children: <Widget>[
|
||||
new FirstPage(),
|
||||
new WidgetPage(db),
|
||||
new ThirdPage(
|
||||
data2ThirdPage: data2ThirdPage,
|
||||
callback: (val) => _onDataChange(val)),
|
||||
new CollectionPage(),
|
||||
new FourthPage()
|
||||
]),
|
||||
bottomNavigationBar: new Material(
|
||||
color: const Color(0xFFF0EEEF), //底部导航栏主题颜色
|
||||
child: new Container(
|
||||
height: 65.0,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF0F0F0),
|
||||
boxShadow: <BoxShadow>[
|
||||
new BoxShadow(
|
||||
color: const Color(0xFFd0d0d0),
|
||||
blurRadius: 3.0,
|
||||
spreadRadius: 2.0,
|
||||
offset: Offset(-1.0, -1.0),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: new TabBar(
|
||||
controller: controller,
|
||||
indicatorColor: Colors.blue, //tab标签的下划线颜色
|
||||
labelColor: const Color(0xFF000000),
|
||||
indicatorColor:
|
||||
Theme.of(context).primaryColor, //tab标签的下划线颜色
|
||||
// labelColor: const Color(0xFF000000),
|
||||
indicatorWeight: 3.0,
|
||||
labelColor: Theme.of(context).primaryColor,
|
||||
unselectedLabelColor: const Color(0xFF8E8E8E),
|
||||
tabs: <Tab>[
|
||||
new Tab(text: '业界动态', icon: new Icon(Icons.language)),
|
||||
new Tab(text: '组件', icon: new Icon(Icons.extension)),
|
||||
new Tab(text: '官网地址', icon: new Icon(Icons.home)),
|
||||
new Tab(text: '组件收藏', icon: new Icon(Icons.star)),
|
||||
new Tab(text: '关于手册', icon: new Icon(Icons.favorite)),
|
||||
]))));
|
||||
}
|
||||
|
||||
void _onTabChange() {
|
||||
if (this.mounted) {
|
||||
this.setState(() {
|
||||
appBarTitle = tabData[controller.index]['text'];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void _onDataChange(val) {
|
||||
if (this.mounted) {
|
||||
setState(() {
|
||||
data = val;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
68
lib/model/collection.dart
Normal file
68
lib/model/collection.dart
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* @Author: 一凨
|
||||
* @Date: 2019-01-07 16:24:42
|
||||
* @Last Modified by: 一凨
|
||||
* @Last Modified time: 2019-01-08 17:37:42
|
||||
*/
|
||||
import 'dart:async';
|
||||
import '../common/sql.dart';
|
||||
|
||||
abstract class CollectionInterface {
|
||||
String get name;
|
||||
String get router;
|
||||
}
|
||||
|
||||
class Collection implements CollectionInterface {
|
||||
String name;
|
||||
String router;
|
||||
|
||||
Collection({this.name, this.router});
|
||||
|
||||
factory Collection.fromJSON(Map json){
|
||||
return Collection(name: json['name'],router: json['router']);
|
||||
}
|
||||
|
||||
Object toMap() {
|
||||
return {'name': name, 'router': router};
|
||||
}
|
||||
}
|
||||
|
||||
class CollectionControlModel {
|
||||
final String table = 'collection';
|
||||
Sql sql;
|
||||
|
||||
CollectionControlModel() {
|
||||
sql = Sql.setTable(table);
|
||||
}
|
||||
|
||||
// 获取所有的收藏
|
||||
|
||||
// 插入新收藏
|
||||
Future insert(Collection collection) {
|
||||
var result =
|
||||
sql.insert({'name': collection.name, 'router': collection.router});
|
||||
return result;
|
||||
}
|
||||
|
||||
// 获取全部的收藏
|
||||
Future<List<Collection>> getAllCollection() async {
|
||||
List list = await sql.getByCondition();
|
||||
List<Collection> resultList = [];
|
||||
list.forEach((item){
|
||||
print(item);
|
||||
resultList.add(Collection.fromJSON(item));
|
||||
});
|
||||
return resultList;
|
||||
}
|
||||
|
||||
// 通过收藏名获取router
|
||||
Future getRouterByName(String name) async {
|
||||
List list = await sql.getByCondition(conditions: {'name': name});
|
||||
return list;
|
||||
}
|
||||
|
||||
// 删除
|
||||
Future deleteByName(String name) async{
|
||||
return await sql.delete(name,'name');
|
||||
}
|
||||
}
|
@ -5,9 +5,7 @@ import '../widgets/404.dart';
|
||||
|
||||
var categoryHandler = new Handler(
|
||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||
print("params $params");
|
||||
String name = params["type"]?.first;
|
||||
print("type::: $name");
|
||||
|
||||
return new CategoryHome(name);
|
||||
},
|
||||
|
@ -13,7 +13,6 @@ class Routes {
|
||||
List widgetDemosList = new WidgetDemoList().getDemos();
|
||||
router.notFoundHandler = new Handler(
|
||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||
print("ROUTE WAS NOT FOUND !!!");
|
||||
});
|
||||
|
||||
|
||||
@ -22,11 +21,9 @@ class Routes {
|
||||
widgetDemosList.forEach((demo) {
|
||||
Handler handler = new Handler(
|
||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||
print('detail路由:${demo.buildRouter(context)}');
|
||||
return demo.buildRouter(context);
|
||||
});
|
||||
|
||||
print('路由:${demo.routerName}');
|
||||
|
||||
router.define('${demo.routerName}', handler: handler);
|
||||
});
|
||||
|
@ -47,7 +47,6 @@ class FirstPageState extends State<FirstPage> {
|
||||
resultList.add(cellData);
|
||||
} catch (e) {
|
||||
// No specified type, handles all
|
||||
print('Something really unknown: $i');
|
||||
}
|
||||
}
|
||||
Map<String, dynamic> result = {"list":resultList, 'total':pageTotal, 'pageIndex':pageIndex};
|
||||
|
@ -40,7 +40,6 @@ class ThirdPageState extends State<ThirdPage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
print('===========>>>:123123123123');
|
||||
return new Center(
|
||||
child: new Column(children: <Widget>[
|
||||
new Container(
|
||||
|
@ -86,14 +86,12 @@ class _CategoryHome extends State<CategoryHome> {
|
||||
void onWidgetTap(WidgetPoint widgetPoint) {
|
||||
String targetName = widgetPoint.name;
|
||||
String targetRouter = '/category/error/404';
|
||||
print("widgetDemosList> ${widgetDemosList}");
|
||||
widgetDemosList.forEach((item) {
|
||||
// print("targetRouter = item.routerName> ${[item.name,targetName]}");
|
||||
if (item.name == targetName) {
|
||||
targetRouter = item.routerName;
|
||||
}
|
||||
});
|
||||
print("router> ${targetRouter}");
|
||||
Application.router.navigateTo(context, "${targetRouter}");
|
||||
}
|
||||
|
||||
|
35
lib/views/collection_page.dart
Normal file
35
lib/views/collection_page.dart
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* @Author: 一凨
|
||||
* @Date: 2019-01-08 17:12:58
|
||||
* @Last Modified by: 一凨
|
||||
* @Last Modified time: 2019-01-08 20:14:56
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
import '../model/collection.dart';
|
||||
|
||||
class CollectionPage extends StatefulWidget {
|
||||
_CollectionPageState createState() => _CollectionPageState();
|
||||
}
|
||||
|
||||
class _CollectionPageState extends State<CollectionPage> {
|
||||
CollectionControlModel _collectionControl = new CollectionControlModel();
|
||||
List<Collection> _collectionList = [];
|
||||
@override
|
||||
void initState() {
|
||||
// TODO: implement initState
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
_collectionControl.getAllCollection().then((resultList) {
|
||||
_collectionList = resultList;
|
||||
_collectionList.forEach((item){
|
||||
print(item.toMap());
|
||||
});
|
||||
});
|
||||
return Container(
|
||||
child: Text('敬请期待'),
|
||||
);
|
||||
}
|
||||
}
|
135
lib/widgets/components/Bar/AppBar/demo.dart
Normal file
135
lib/widgets/components/Bar/AppBar/demo.dart
Normal file
@ -0,0 +1,135 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2019/1/1
|
||||
* Time: 下午7:33
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: AppBar 的示例
|
||||
*/
|
||||
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/*
|
||||
* Checkbox 默认按钮的实例
|
||||
* index 当前checkbox 的索引值
|
||||
* */
|
||||
class AppBarLessDefaultComplex extends StatefulWidget {
|
||||
const AppBarLessDefaultComplex() : super();
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _AppBarLessDefaultComplex();
|
||||
}
|
||||
|
||||
/*
|
||||
* AppBar 默认的实例,有状态
|
||||
* */
|
||||
class _AppBarLessDefaultComplex extends State with SingleTickerProviderStateMixin {
|
||||
ScrollController _scrollViewController;
|
||||
TabController _tabController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_scrollViewController = new ScrollController();
|
||||
_tabController = new TabController(vsync: this, length: 6);// 和下面的 TabBar.tabs 数量对应
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_scrollViewController.dispose();
|
||||
_tabController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// 如果省略了 leading ,但 AppBar 在带有 Drawer 的 Scaffold 中,则会插入一个 button 以打开 Drawer。
|
||||
// 否则,如果最近的 Navigator 具有任何先前的 router ,则会插入BackButton。
|
||||
// 这种行为可以通过设置来关闭automaticallyImplyLeading 为false。在这种情况下,空的 leading widget 将导致 middle/title widget 拉伸开始。
|
||||
return new SizedBox(
|
||||
height: 500,
|
||||
child:new AppBar( // 大量配置属性参考 SliverAppBar 示例
|
||||
title: new Text('title'),
|
||||
leading: new Icon(Icons.home),
|
||||
backgroundColor: Colors.amber[500],
|
||||
centerTitle: true,
|
||||
actions: <Widget>[
|
||||
new IconButton(
|
||||
icon: new Icon(Icons.add_alarm),
|
||||
tooltip: 'Add Alarm',
|
||||
onPressed: () {
|
||||
// do nothing
|
||||
}),
|
||||
new PopupMenuButton<String>(
|
||||
itemBuilder: (BuildContext context) => <PopupMenuItem<String>>[
|
||||
new PopupMenuItem<String>(
|
||||
value: "price", child: new Text('Sort by price')),
|
||||
new PopupMenuItem<String>(
|
||||
value: "time", child: new Text('Sort by time')),
|
||||
],
|
||||
onSelected: (String action) {
|
||||
switch (action) {
|
||||
case "price":
|
||||
// do nothing
|
||||
break;
|
||||
case "time":
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
})
|
||||
],
|
||||
bottom: new TabBar(
|
||||
isScrollable: true,
|
||||
controller: _tabController,
|
||||
tabs: <Widget>[
|
||||
new Tab(text: "Tabs 1"),
|
||||
new Tab(text: "Tabs 2"),
|
||||
new Tab(text: "Tabs 3"),
|
||||
new Tab(text: "Tabs 4"),
|
||||
new Tab(text: "Tabs 5"),
|
||||
new Tab(text: "Tabs 6"),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* AppBar 默认的实例,无状态
|
||||
* */
|
||||
class AppBarLessDefaultSimple extends StatelessWidget {
|
||||
final widget;
|
||||
final parent;
|
||||
|
||||
const AppBarLessDefaultSimple([this.widget, this.parent])
|
||||
: super();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new SizedBox(
|
||||
height: 200,
|
||||
child:AppBar(
|
||||
title: Text('My Fancy Dress'),
|
||||
actions: <Widget>[
|
||||
IconButton(
|
||||
icon: Icon(Icons.playlist_play),
|
||||
tooltip: 'Air it',
|
||||
onPressed: ()=>{},
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.playlist_add),
|
||||
tooltip: 'Restitch it',
|
||||
onPressed: ()=>{},
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.playlist_add_check),
|
||||
tooltip: 'Repair it',
|
||||
onPressed: ()=>{},
|
||||
),
|
||||
],
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
97
lib/widgets/components/Bar/AppBar/index.dart
Normal file
97
lib/widgets/components/Bar/AppBar/index.dart
Normal file
@ -0,0 +1,97 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2019/1/1
|
||||
* Time: 下午7:30
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: AppBar 的示例
|
||||
*/
|
||||
import '../../../../common/widget-demo.dart';
|
||||
import '../../../../routers/application.dart';
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import './demo.dart' as AppBarDemo;
|
||||
|
||||
const String _Text0 =
|
||||
"""### **简介**
|
||||
> AppBar “应用栏”
|
||||
- 应用栏由工具栏和可能的其他 widget 组成,例如 TabBar和FlexibleSpaceBar。
|
||||
- 应用栏通常用于 Scaffold.appBa r属性,该属性将应用栏放置在屏幕顶部的固定高度小部件中。
|
||||
- 对于可滚动的应用栏,请参阅SliverAppBar,它将AppBar嵌入 sliver 中以便在CustomScrollView中使用。
|
||||
""";
|
||||
|
||||
|
||||
const String _Text1 =
|
||||
"""### **基本用法**
|
||||
> AppBar
|
||||
- AppBar 在底部上方显示工具栏 widget,前导 leading ,标题 title 和操作 actions。
|
||||
""";
|
||||
|
||||
const String _Text2 =
|
||||
"""### **进阶用法**
|
||||
> AppBar
|
||||
- 一个完整的 AppBar 的例子, 增加 PopupMenuButton,TabBar 的示例子。
|
||||
- 所述底部通常用于一个的TabBar。如果指定了flexibleSpace窗口小部件,则它将堆叠在工具栏和底部窗口 widget 后面。
|
||||
""";
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Bar/AppBar';
|
||||
|
||||
@override
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
title: 'AppBar',
|
||||
codeUrl: '${Application.github['widgetsURL']}componentss/Bar/AppBar/demo.dart',
|
||||
child: allCheckboxs(context, this),
|
||||
docUrl: 'https://docs.flutter.io/flutter/material/AppBar-class.html',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 所有的 AppBar widget
|
||||
* context: 运行上下文
|
||||
* that: 指向有状态的 StatefulWidget
|
||||
*/
|
||||
Widget allCheckboxs(BuildContext context, _DemoState that) {
|
||||
return Container(
|
||||
//padding: new EdgeInsets.only(bottom: 20.0, top: 20.0, left: 0, right: 0),
|
||||
child: Column(
|
||||
//mainAxisSize: MainAxisSize.max,
|
||||
children: <Widget>[
|
||||
MarkdownBody(data: _Text0),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
MarkdownBody(data: _Text1),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
AppBarDemo.AppBarLessDefaultSimple(),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
MarkdownBody(data: _Text2),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
AppBarDemo.AppBarLessDefaultComplex(),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* 带align的text
|
||||
* */
|
||||
Widget textAlignBar(String txt) {
|
||||
return new Align(
|
||||
alignment: FractionalOffset.centerLeft,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
SizedBox(height: 20.0),
|
||||
MarkdownBody(data: txt)
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
|
47
lib/widgets/components/Bar/BottomAppBar/demo.dart
Normal file
47
lib/widgets/components/Bar/BottomAppBar/demo.dart
Normal file
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2019/1/1
|
||||
* Time: 下午8:56
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: BottomAppBar 的示例
|
||||
*/
|
||||
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/*
|
||||
* AppBar 默认的实例,无状态
|
||||
* */
|
||||
class AppBarLessDefaultSimple extends StatelessWidget {
|
||||
final widget;
|
||||
final parent;
|
||||
|
||||
const AppBarLessDefaultSimple([this.widget, this.parent])
|
||||
: super();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new SizedBox(
|
||||
height: 100,
|
||||
child: Scaffold(
|
||||
//appBar: AppBar(title: const Text('Bottom App Bar')),
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
|
||||
floatingActionButton: FloatingActionButton(
|
||||
child: const Icon(Icons.add), onPressed: () {},),
|
||||
bottomNavigationBar: BottomAppBar(
|
||||
shape: CircularNotchedRectangle(),
|
||||
notchMargin: 10.0,// FloatingActionButton和BottomAppBar 之间的差距
|
||||
color:Colors.pink,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
IconButton(icon: Icon(Icons.menu), onPressed: () {},),
|
||||
IconButton(icon: Icon(Icons.search), onPressed: () {},),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
}}
|
76
lib/widgets/components/Bar/BottomAppBar/index.dart
Normal file
76
lib/widgets/components/Bar/BottomAppBar/index.dart
Normal file
@ -0,0 +1,76 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2019/1/1
|
||||
* Time: 下午8:53
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: BottomAppBar 的示例
|
||||
*/
|
||||
import '../../../../common/widget-demo.dart';
|
||||
import '../../../../routers/application.dart';
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import './demo.dart' as BottomAppBarDemo;
|
||||
|
||||
const String _Text0 =
|
||||
"""### **简介**
|
||||
> BottomAppBar “底部应用栏”
|
||||
- 一个通常与 Scaffold.bottomNavigationBar 一起使用的容器,可以在顶部有一个凹口,为重叠的FloatingActionButton腾出空间 。
|
||||
""";
|
||||
|
||||
|
||||
const String _Text1 =
|
||||
"""### **基本用法**
|
||||
> 通常与Scaffold和FloatingActionButton一起使用。
|
||||
""";
|
||||
|
||||
const String _Text2 =
|
||||
"""### **进阶用法**
|
||||
> BottomAppBar
|
||||
-
|
||||
""";
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components//Bar/BottomAppBar';
|
||||
|
||||
@override
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
title: 'BottomAppBar',
|
||||
codeUrl: '${Application.github['widgetsURL']}componentss/Bar/BottomAppBar/demo.dart',
|
||||
child: allCheckboxs(context, this),
|
||||
docUrl: 'https://docs.flutter.io/flutter/material/BottomAppBar-class.html',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 所有的 BottomAppBar widget
|
||||
* context: 运行上下文
|
||||
* that: 指向有状态的 StatefulWidget
|
||||
*/
|
||||
Widget allCheckboxs(BuildContext context, _DemoState that) {
|
||||
return Container(
|
||||
//padding: new EdgeInsets.only(bottom: 20.0, top: 20.0, left: 0, right: 0),
|
||||
child: Column(
|
||||
//mainAxisSize: MainAxisSize.max,
|
||||
children: <Widget>[
|
||||
MarkdownBody(data: _Text0),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
MarkdownBody(data: _Text1),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
BottomAppBarDemo.AppBarLessDefaultSimple(),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
76
lib/widgets/components/Bar/ButtonBar/demo.dart
Normal file
76
lib/widgets/components/Bar/ButtonBar/demo.dart
Normal file
@ -0,0 +1,76 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2019/1/1
|
||||
* Time: 下午11:11
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: ButtonBar 的示例
|
||||
*/
|
||||
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/*
|
||||
* Checkbox 默认按钮的实例
|
||||
* index 当前checkbox 的索引值
|
||||
* */
|
||||
class ButtonBarFullDefault extends StatefulWidget {
|
||||
const ButtonBarFullDefault() : super();
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _ButtonBarFullDefault();
|
||||
}
|
||||
|
||||
/*
|
||||
* ButtonBar 默认的实例,有状态
|
||||
* */
|
||||
class _ButtonBarFullDefault extends State {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ButtonBar(
|
||||
// ... // 如果没有,就是不需要有状态的 StatefulWidget
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ButtonBar 默认的实例,无状态
|
||||
* */
|
||||
class ButtonBarLessDefault extends StatelessWidget {
|
||||
final widget;
|
||||
final parent;
|
||||
|
||||
const ButtonBarLessDefault([this.widget, this.parent])
|
||||
: super();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
margin: new EdgeInsets.symmetric(vertical: 0.0),
|
||||
height: 100.0,
|
||||
child: new Scrollbar(child:ListView(
|
||||
scrollDirection: Axis.horizontal, // 水平listView
|
||||
children: <Widget>[
|
||||
ButtonBar(
|
||||
alignment: MainAxisAlignment.spaceAround, //布局方向,默认MainAxisAlignment.end
|
||||
mainAxisSize: MainAxisSize.max, //主轴大小,默认MainAxisSize.max
|
||||
children: <Widget>[ // Button集合
|
||||
RaisedButton(child: Text('ButtonBar1'),color: Colors.red,onPressed: ()=>{},),
|
||||
RaisedButton(child: Text('ButtonBar2'),color: Colors.red,onPressed: ()=>{},),
|
||||
RaisedButton(child: Text('ButtonBar3'),color: Colors.red,onPressed: ()=>{},),
|
||||
],
|
||||
),
|
||||
ButtonBar(
|
||||
alignment: MainAxisAlignment.end, //布局方向,默认MainAxisAlignment.end
|
||||
mainAxisSize: MainAxisSize.min, //主轴大小,默认MainAxisSize.max
|
||||
children: <Widget>[ // Button集合
|
||||
RaisedButton(child: Text('ButtonBar1'),color: Colors.yellow,onPressed: ()=>{},),
|
||||
RaisedButton(child: Text('ButtonBar2'),color: Colors.yellow,onPressed: ()=>{},),
|
||||
RaisedButton(child: Text('ButtonBar3'),color: Colors.yellow,onPressed: ()=>{},),
|
||||
],
|
||||
)
|
||||
]
|
||||
)
|
||||
));
|
||||
}
|
||||
}
|
75
lib/widgets/components/Bar/ButtonBar/index.dart
Normal file
75
lib/widgets/components/Bar/ButtonBar/index.dart
Normal file
@ -0,0 +1,75 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2019/1/1
|
||||
* Time: 下午11:10
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: ButtonBar 的示例
|
||||
*/
|
||||
import '../../../../common/widget-demo.dart';
|
||||
import '../../../../routers/application.dart';
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import './demo.dart' as ButtonBarDemo;
|
||||
|
||||
const String _Text0 =
|
||||
"""### **简介**
|
||||
> ButtonBar “末端对齐的按钮容器”
|
||||
- 横排的Button布局
|
||||
""";
|
||||
|
||||
|
||||
const String _Text1 =
|
||||
"""### **基本用法**
|
||||
> 根据当前ButtonTheme中的填充水平放置按钮 。子 button 在布置行与 MainAxisAlignment.end
|
||||
- 当Directionality为TextDirection.ltr时,按钮栏的子项右对齐,最后一个子项成为最右边的子项。当Directionality TextDirection.rtl时,子项被左对齐,最后一个子项成为最左边的子项。
|
||||
""";
|
||||
|
||||
const String _Text2 =
|
||||
"""### **进阶用法**
|
||||
> ButtonBar
|
||||
-
|
||||
""";
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Bar/ButtonBar';
|
||||
|
||||
@override
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
title: 'ButtonBar',
|
||||
codeUrl: '${Application
|
||||
.github['widgetsURL']}componentss//Bar/ButtonBar/demo.dart',
|
||||
child: allCheckboxs(context, this),
|
||||
docUrl: 'https://docs.flutter.io/flutter/material/ButtonBar-class.html',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 所有的 ButtonBar widget
|
||||
* context: 运行上下文
|
||||
* that: 指向有状态的 StatefulWidget
|
||||
*/
|
||||
Widget allCheckboxs(BuildContext context, _DemoState that) {
|
||||
return Container(
|
||||
//padding: new EdgeInsets.only(bottom: 20.0, top: 20.0, left: 0, right: 0),
|
||||
child: Column(
|
||||
//mainAxisSize: MainAxisSize.max,
|
||||
children: <Widget>[
|
||||
MarkdownBody(data: _Text0),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
MarkdownBody(data: _Text1),
|
||||
//SizedBox(height: 20.0), // 间距
|
||||
ButtonBarDemo.ButtonBarLessDefault()
|
||||
])
|
||||
);
|
||||
}
|
||||
|
78
lib/widgets/components/Bar/FlexibleSpaceBar/demo.dart
Normal file
78
lib/widgets/components/Bar/FlexibleSpaceBar/demo.dart
Normal file
@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2019/1/1
|
||||
* Time: 下午10:38
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: FlexibleSpaceBar 的示例
|
||||
*/
|
||||
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/*
|
||||
* Checkbox 默认按钮的实例
|
||||
* index 当前checkbox 的索引值
|
||||
* */
|
||||
class FlexibleSpaceBarFullDefault extends StatefulWidget {
|
||||
const FlexibleSpaceBarFullDefault() : super();
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _FlexibleSpaceBarFullDefault();
|
||||
}
|
||||
|
||||
/*
|
||||
* FlexibleSpaceBar 默认的实例,有状态
|
||||
* */
|
||||
class _FlexibleSpaceBarFullDefault extends State {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FlexibleSpaceBar(
|
||||
// ... // 如果没有,就是不需要有状态的 StatefulWidget
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* FlexibleSpaceBar 默认的实例,无状态
|
||||
* */
|
||||
class FlexibleSpaceBarLessDefault extends StatelessWidget {
|
||||
final widget;
|
||||
final parent;
|
||||
|
||||
const FlexibleSpaceBarLessDefault([this.widget, this.parent])
|
||||
: super();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
height: 300.0,
|
||||
child: Scaffold(
|
||||
body: NestedScrollView(
|
||||
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
|
||||
return <Widget>[
|
||||
SliverAppBar(
|
||||
expandedHeight: 150.0,
|
||||
floating: false,
|
||||
pinned: true,
|
||||
flexibleSpace: FlexibleSpaceBar(
|
||||
centerTitle: true,
|
||||
title: Text("Collapsing Toolbar",
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 16.0,
|
||||
)),
|
||||
background: Image.network(
|
||||
"https://images.pexels.com/photos/396547/pexels-photo-396547.jpeg?auto=compress&cs=tinysrgb&h=350",
|
||||
fit: BoxFit.cover,
|
||||
)),
|
||||
),
|
||||
];
|
||||
},
|
||||
body: Center(
|
||||
child: Text("向上提拉 ⬆ 查看效果..."),
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
}}
|
77
lib/widgets/components/Bar/FlexibleSpaceBar/index.dart
Normal file
77
lib/widgets/components/Bar/FlexibleSpaceBar/index.dart
Normal file
@ -0,0 +1,77 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2019/1/1
|
||||
* Time: 下午10:38
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: FlexibleSpaceBar 的示例
|
||||
*/
|
||||
import '../../../../common/widget-demo.dart';
|
||||
import '../../../../routers/application.dart';
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import './demo.dart' as FlexibleSpaceBarDemo;
|
||||
|
||||
const String _Text0 =
|
||||
"""### **简介**
|
||||
> FlexibleSpaceBar “扩展和折叠的应用栏”
|
||||
- AppBar的一部分,可以扩展和折叠。
|
||||
""";
|
||||
|
||||
|
||||
const String _Text1 =
|
||||
"""### **基本用法**
|
||||
> 最常用于 SliverAppBar.flexibleSpace 字段
|
||||
- 灵活的空格键随着应用滚动而扩展和收缩,以便AppBar 从应用程序的顶部到达应用程序滚动内容的顶部。
|
||||
- 要调整 AppBar 大小,必须将其包装在 FlexibleSpaceBar.createSettings 返回的 widget 中 ,以将大小调整信息传递给 FlexibleSpaceBar。
|
||||
""";
|
||||
|
||||
const String _Text2 =
|
||||
"""### **进阶用法**
|
||||
> FlexibleSpaceBar
|
||||
-
|
||||
""";
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components//Bar/FlexibleSpaceBar';
|
||||
|
||||
@override
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
title: 'FlexibleSpaceBar',
|
||||
codeUrl: '${Application
|
||||
.github['widgetsURL']}componentss/Bar/FlexibleSpaceBar/demo.dart',
|
||||
child: allCheckboxs(context, this),
|
||||
docUrl: 'https://docs.flutter.io/flutter/material/FlexibleSpaceBar-class.html',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 所有的 FlexibleSpaceBar widget
|
||||
* context: 运行上下文
|
||||
* that: 指向有状态的 StatefulWidget
|
||||
*/
|
||||
Widget allCheckboxs(BuildContext context, _DemoState that) {
|
||||
return Container(
|
||||
//padding: new EdgeInsets.only(bottom: 20.0, top: 20.0, left: 0, right: 0),
|
||||
child: Column(
|
||||
//mainAxisSize: MainAxisSize.max,
|
||||
children: <Widget>[
|
||||
MarkdownBody(data: _Text0),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
MarkdownBody(data: _Text1),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
FlexibleSpaceBarDemo.FlexibleSpaceBarLessDefault(),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
])
|
||||
);
|
||||
}
|
||||
|
165
lib/widgets/components/Bar/SliverAppBar/demo.dart
Normal file
165
lib/widgets/components/Bar/SliverAppBar/demo.dart
Normal file
@ -0,0 +1,165 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2019/1/1
|
||||
* Time: 下午4:11
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: SliverAppBar 的示例
|
||||
*/
|
||||
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/*
|
||||
* Checkbox 默认按钮的实例
|
||||
* index 当前checkbox 的索引值
|
||||
* */
|
||||
class SliverAppBarFullDefault extends StatefulWidget {
|
||||
const SliverAppBarFullDefault() : super();
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _SliverAppBarFullDefault();
|
||||
}
|
||||
|
||||
/*
|
||||
* SliverAppBar 默认的实例,有状态
|
||||
* */
|
||||
class _SliverAppBarFullDefault extends State {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SliverAppBar(
|
||||
// ... // 如果没有,就是不需要有状态的 StatefulWidget
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SliverAppBar 默认的实例,无状态
|
||||
* */
|
||||
class SliverAppBarLessDefault extends StatelessWidget {
|
||||
// final widget;
|
||||
// final parent;
|
||||
// const SliverAppBarLessDefault([this.widget, this.parent])
|
||||
// : super();
|
||||
|
||||
final List<ListItem> listData = [];
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
for (int i = 0; i < 20; i++) {
|
||||
listData.add(new ListItem("我是测试标题$i", Icons.cake));
|
||||
}
|
||||
return new SizedBox(
|
||||
height: 500.0,
|
||||
child:NestedScrollView(
|
||||
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
|
||||
return <Widget>[
|
||||
SliverAppBar(
|
||||
//leading, // 在标题前面显示的一个控件,在首页通常显示应用的 logo;在其他界面通常显示为返回按钮
|
||||
//title, // Toolbar 中主要内容,通常显示为当前界面的标题文字
|
||||
//actions, // 一个 Widget 列表,代表 Toolbar 中所显示的菜单,对于常用的菜单,通常使用 IconButton 来表示;对于不常用的菜单通常使用 PopupMenuButton 来显示为三个点,点击后弹出二级菜单
|
||||
//flexibleSpace,
|
||||
//bottom, //底部内容区域
|
||||
//elevation, //阴影,纸墨设计中控件的 z 坐标顺序,默认值为 4,对于可滚动的 SliverAppBar,当 SliverAppBar 和内容同级的时候,该值为 0, 当内容滚动 SliverAppBar 变为 Toolbar 的时候,修改 elevation 的值
|
||||
//flexibleSpace:一个显示在 AppBar 下方的控件,高度和 AppBar 高度一样,可以实现一些特殊的效果,该属性通常在 SliverAppBar 中使用
|
||||
//backgroundColor, // 背景色,APP bar 的颜色,默认值为 ThemeData.primaryColor。改值通常和下面的三个属性一起使用
|
||||
//brightness, // 主题明亮,App bar 的亮度,有白色和黑色两种主题,默认值为 ThemeData.primaryColorBrightness
|
||||
//iconTheme, // 图标主题,App bar 上图标的颜色、透明度、和尺寸信息。默认值为 ThemeData.primaryIconTheme
|
||||
//textTheme, //文字主题, App bar 上的文字样式。默认值为 ThemeData.primaryTextTheme
|
||||
//centerTitle, //标题是否居中, 标题是否居中显示,默认值根据不同的操作系统,显示方式不一样
|
||||
primary: true, //是否预留高度
|
||||
forceElevated:false,
|
||||
automaticallyImplyLeading:true,
|
||||
titleSpacing: NavigationToolbar.kMiddleSpacing,
|
||||
snap:false, //与floating结合使用
|
||||
expandedHeight: 200.0,//展开高度
|
||||
floating: false,//是否随着滑动隐藏标题
|
||||
pinned: true,//是否固定在顶部
|
||||
flexibleSpace: FlexibleSpaceBar( //可以展开区域,通常是一个FlexibleSpaceBar
|
||||
centerTitle: true,
|
||||
title: Text("我是一个帅气的标题",
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 16.0,
|
||||
)),
|
||||
background: Image.network(
|
||||
//"http://h.hiphotos.baidu.com/image/pic/item/342ac65c103853434cc02dda9f13b07eca80883a.jpg",
|
||||
"http://b.zol-img.com.cn/desk/bizhi/image/6/960x600/1432800027589.jpg",
|
||||
//"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1531798262708&di=53d278a8427f482c5b836fa0e057f4ea&imgtype=0&src=http%3A%2F%2Fh.hiphotos.baidu.com%2Fimage%2Fpic%2Fitem%2F342ac65c103853434cc02dda9f13b07eca80883a.jpg",
|
||||
fit: BoxFit.fill,
|
||||
)),
|
||||
),
|
||||
// SliverPersistentHeader(
|
||||
// delegate: _SliverAppBarDelegate(
|
||||
// TabBar(
|
||||
// controller: new TabController(length: 2, vsync: this),
|
||||
// labelColor: Colors.black87,
|
||||
// unselectedLabelColor: Colors.grey,
|
||||
// tabs: [
|
||||
// Tab(icon: Icon(Icons.security), text: "security"),
|
||||
// Tab(icon: Icon(Icons.cake), text: "cake"),
|
||||
// ],
|
||||
// ),
|
||||
// ))
|
||||
];
|
||||
},
|
||||
body: Center(
|
||||
child: new ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return new ListItemWidget(listData[index]);
|
||||
},
|
||||
itemCount: listData.length,
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
class ListItem {
|
||||
final String title;
|
||||
final IconData iconData;
|
||||
|
||||
ListItem(this.title, this.iconData);
|
||||
}
|
||||
|
||||
class ListItemWidget extends StatelessWidget {
|
||||
final ListItem listItem;
|
||||
|
||||
ListItemWidget(this.listItem);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new InkWell(
|
||||
child: new ListTile(
|
||||
leading: new Icon(listItem.iconData),
|
||||
title: new Text(listItem.title),
|
||||
),
|
||||
onTap: () {},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
|
||||
_SliverAppBarDelegate(this._tabBar);
|
||||
|
||||
final TabBar _tabBar;
|
||||
|
||||
@override
|
||||
double get minExtent => _tabBar.preferredSize.height;
|
||||
|
||||
@override
|
||||
double get maxExtent => _tabBar.preferredSize.height;
|
||||
|
||||
@override
|
||||
Widget build(
|
||||
BuildContext context, double shrinkOffset, bool overlapsContent) {
|
||||
return new Container(
|
||||
child: _tabBar,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
|
||||
return false;
|
||||
}
|
||||
}
|
85
lib/widgets/components/Bar/SliverAppBar/index.dart
Normal file
85
lib/widgets/components/Bar/SliverAppBar/index.dart
Normal file
@ -0,0 +1,85 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2019/1/1
|
||||
* Time: 下午4:10
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: SliverAppBar 的示例
|
||||
*/
|
||||
import '../../../../common/widget-demo.dart';
|
||||
import '../../../../routers/application.dart';
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import './demo.dart' as SliverAppBarDemo;
|
||||
|
||||
const String _Text0 =
|
||||
"""### **简介**
|
||||
> SliverAppBar “应用栏”
|
||||
- 它类似于Android中的toolbar。
|
||||
""";
|
||||
|
||||
|
||||
const String _Text1 =
|
||||
"""### **基本用法**
|
||||
> 虽然基本相同,构造方法也是非常的简单,但是却不能直接使用它,由官方文档可以看到通常结合ScrollView来使用它。
|
||||
- AppBar 和 SliverAppBar 都是继承StatefulWidget 类,都代表 Toobar。
|
||||
- 二者的区别在于 AppBar 位置的固定的应用最上面的;而 SliverAppBar 是可以跟随内容滚动的。
|
||||
- 下面的示例,放在 NestedScrollView 实现上提到顶的悬停。
|
||||
""";
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Bar/SliverAppBar';
|
||||
|
||||
@override
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
title: 'SliverAppBar',
|
||||
codeUrl: '${Application.github['widgetsURL']}componentss/Bar/SliverAppBar/demo.dart',
|
||||
child: allCheckboxs(context, this),
|
||||
docUrl: 'https://docs.flutter.io/flutter/widgets/SliverAppBar-class.html',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 所有的 SliverAppBar widget
|
||||
* context: 运行上下文
|
||||
* that: 指向有状态的 StatefulWidget
|
||||
*/
|
||||
Widget allCheckboxs(BuildContext context, _DemoState that) {
|
||||
return Container(
|
||||
//padding: new EdgeInsets.only(bottom: 20.0, top: 20.0, left: 0, right: 0),
|
||||
child: Column(
|
||||
//mainAxisSize: MainAxisSize.max,
|
||||
children: <Widget>[
|
||||
MarkdownBody(data: _Text0),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
MarkdownBody(data: _Text1),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
SliverAppBarDemo.SliverAppBarLessDefault()
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* 带align的text
|
||||
* */
|
||||
Widget textAlignBar(String txt) {
|
||||
return new Align(
|
||||
alignment: FractionalOffset.centerLeft,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
SizedBox(height: 20.0),
|
||||
MarkdownBody(data: txt)
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
|
87
lib/widgets/components/Bar/SnackBar/demo.dart
Normal file
87
lib/widgets/components/Bar/SnackBar/demo.dart
Normal file
@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2019/1/2
|
||||
* Time: 上午12:07
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: SnackBar 的示例
|
||||
*/
|
||||
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/*
|
||||
* Checkbox 默认按钮的实例
|
||||
* index 当前checkbox 的索引值
|
||||
* */
|
||||
class SnackBarFullDefault extends StatefulWidget {
|
||||
const SnackBarFullDefault() : super();
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _SnackBarFullDefault();
|
||||
}
|
||||
|
||||
/*
|
||||
* SnackBar 默认的实例,有状态
|
||||
* */
|
||||
class _SnackBarFullDefault extends State {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SnackBar(
|
||||
// ... // 如果没有,就是不需要有状态的 StatefulWidget
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SnackBar 默认的实例,无状态
|
||||
* */
|
||||
class SnackBarLessDefault extends StatelessWidget {
|
||||
final widget;
|
||||
final parent;
|
||||
|
||||
const SnackBarLessDefault([this.widget, this.parent])
|
||||
: super();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// 当BuildContext在Scaffold之前时,调用Scaffold.of(context)会报错。这时可以通过Builder Widget来解决
|
||||
return new Center(
|
||||
child: new Column(
|
||||
children: <Widget>[
|
||||
new GestureDetector(
|
||||
onTap: () {
|
||||
final snackBar = new SnackBar(
|
||||
content: new Text('这是一个SnackBar, 右侧有SnackBarAction'),
|
||||
backgroundColor:Colors.red,
|
||||
action: new SnackBarAction( // 提示信息上添加一个撤消的按钮
|
||||
textColor:Colors.black,
|
||||
label: '撤消',
|
||||
onPressed: () {
|
||||
// Some code to undo the change!
|
||||
},
|
||||
),
|
||||
duration:Duration(minutes: 1),// 持续时间
|
||||
//animation,
|
||||
);
|
||||
Scaffold.of(context).showSnackBar(snackBar);
|
||||
},
|
||||
child: new Text('显示SnackBar'),
|
||||
),
|
||||
new GestureDetector(
|
||||
onTap: () {
|
||||
final snackBar = new SnackBar(
|
||||
content: new Text('右侧无SnackBarAction'),
|
||||
backgroundColor:Colors.red,
|
||||
duration:Duration(minutes: 1),// 持续时间
|
||||
//animation,
|
||||
);
|
||||
Scaffold.of(context).showSnackBar(snackBar);
|
||||
},
|
||||
child: new Text('显示无SnackBarAction的SnackBar'),
|
||||
),
|
||||
],
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
91
lib/widgets/components/Bar/SnackBar/index.dart
Normal file
91
lib/widgets/components/Bar/SnackBar/index.dart
Normal file
@ -0,0 +1,91 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2019/1/2
|
||||
* Time: 上午12:06
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: SnackBar 的示例
|
||||
*/
|
||||
import '../../../../common/widget-demo.dart';
|
||||
import '../../../../routers/application.dart';
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import './demo.dart' as SnackBarDemo;
|
||||
|
||||
const String _Text0 =
|
||||
"""### **简介**
|
||||
> SnackBar “屏幕底部消息”
|
||||
- 带有可选操作的轻量级消息,短暂显示在屏幕底部。
|
||||
- SnackBar是用户操作后,显示提示信息的一个控件,类似Toast,会自动隐藏。
|
||||
""";
|
||||
|
||||
|
||||
const String _Text1 =
|
||||
"""### **基本用法**
|
||||
> Scaffold.of(context).showSnackBar(),传递描述消息的SnackBar实例。
|
||||
- 要控制SnackBar保持可见的时间,请指定持续时间。
|
||||
""";
|
||||
|
||||
const String _Text2 =
|
||||
"""### **进阶用法**
|
||||
> SnackBar
|
||||
-
|
||||
""";
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components//Bar/SnackBar';
|
||||
|
||||
@override
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
title: 'SnackBar',
|
||||
codeUrl: '${Application.github['widgetsURL']}componentss/Bar/SnackBar/demo.dart',
|
||||
child: allCheckboxs(context, this),
|
||||
docUrl: 'https://docs.flutter.io/flutter/material/SnackBar-class.html',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 所有的 SnackBar widget
|
||||
* context: 运行上下文
|
||||
* that: 指向有状态的 StatefulWidget
|
||||
*/
|
||||
Widget allCheckboxs(BuildContext context, _DemoState that) {
|
||||
return Container(
|
||||
//padding: new EdgeInsets.only(bottom: 20.0, top: 20.0, left: 0, right: 0),
|
||||
child: Column(
|
||||
//mainAxisSize: MainAxisSize.max,
|
||||
children: <Widget>[
|
||||
MarkdownBody(data: _Text0),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
MarkdownBody(data: _Text1),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
SnackBarDemo.SnackBarLessDefault(),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* 带align的text
|
||||
* */
|
||||
Widget textAlignBar(String txt) {
|
||||
return new Align(
|
||||
alignment: FractionalOffset.centerLeft,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
SizedBox(height: 20.0),
|
||||
MarkdownBody(data: txt)
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
|
61
lib/widgets/components/Bar/SnackBarAction/demo.dart
Normal file
61
lib/widgets/components/Bar/SnackBarAction/demo.dart
Normal file
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: sanfan.hx
|
||||
* Date: 2019/1/6
|
||||
* Time: 下午17:08
|
||||
* email: sanfan.hx@alibaba-inc.com
|
||||
* tartget: SnackBarAction 的示例
|
||||
*/
|
||||
|
||||
import 'dart:math';
|
||||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'demo.dart';
|
||||
|
||||
class SnackBarActionDemo extends StatefulWidget {
|
||||
_Demo createState() => _Demo();
|
||||
}
|
||||
|
||||
class _Demo extends State<SnackBarActionDemo> {
|
||||
Widget build(BuildContext context) {
|
||||
return new Center(
|
||||
child: new Column(
|
||||
children: <Widget>[
|
||||
new GestureDetector(
|
||||
onTap: () {
|
||||
final snackBar = new SnackBar(
|
||||
content: new Text('这是一个SnackBar, 右侧有SnackBarAction, 3秒后消失'),
|
||||
backgroundColor:Color(0xffc91b3a),
|
||||
action: new SnackBarAction( // 提示信息上添加一个撤消的按钮
|
||||
textColor:Colors.white,
|
||||
label: '撤消',
|
||||
onPressed: () {
|
||||
// Some code to undo the change!
|
||||
},
|
||||
),
|
||||
duration:Duration(seconds: 3),// 持续时间
|
||||
//animation,
|
||||
);
|
||||
Scaffold.of(context).showSnackBar(snackBar);
|
||||
},
|
||||
|
||||
child: new Text('点我显示有action的SnackBar'),
|
||||
),
|
||||
new GestureDetector(
|
||||
onTap: () async {
|
||||
final snackBar = new SnackBar(
|
||||
content: new Text('右侧无SnackBarAction, 3秒后消失'),
|
||||
backgroundColor:Color(0xffc91b3a),
|
||||
duration:Duration(seconds: 3),// 持续时间
|
||||
//animation,
|
||||
);
|
||||
Scaffold.of(context).showSnackBar(snackBar);
|
||||
},
|
||||
child: new Text('点我显示无SnackBarAction的SnackBar'),
|
||||
),
|
||||
],
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
50
lib/widgets/components/Bar/SnackBarAction/index.dart
Normal file
50
lib/widgets/components/Bar/SnackBarAction/index.dart
Normal file
@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: sanfan.hx
|
||||
* Date: 2019/1/6
|
||||
* Time: 下午17:08
|
||||
* email: sanfan.hx@alibaba-inc.com
|
||||
* tartget: SnackBarAction 的示例
|
||||
*/
|
||||
import '../../../../common/widget_demo.dart';
|
||||
import '../../../../routers/application.dart';
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../../components/markdown.dart';
|
||||
import './demo.dart' as SnackBarDemo;
|
||||
|
||||
const String _Text0 = """
|
||||
### **简介**
|
||||
> SnackBarAction “屏幕底部消息右侧可操作的行为”
|
||||
|
||||
带有可选操作的轻量级消息,短暂显示在屏幕底部, 并提供按钮交互。
|
||||
|
||||
### **基本用法**
|
||||
|
||||
> 为SnackBar加入action[SnackBarAction]显示按区, 默认下是隐藏的.
|
||||
|
||||
""";
|
||||
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Bar/SnackBarAction';
|
||||
|
||||
@override
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
title: 'SnackBarAction',
|
||||
codeUrl: 'components/Bar/SnackBarAction/demo.dart',
|
||||
contentList: [
|
||||
_Text0,
|
||||
SnackBarDemo.SnackBarActionDemo(),
|
||||
],
|
||||
docUrl: 'https://docs.flutter.io/flutter/material/SnackBarAction-class.html',
|
||||
);
|
||||
}
|
||||
}
|
78
lib/widgets/components/Bar/TabBar/demo.dart
Normal file
78
lib/widgets/components/Bar/TabBar/demo.dart
Normal file
@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2019/1/6
|
||||
* Time: 下午7:33
|
||||
* email: sanfann@alibaba-inc.com
|
||||
* tartget: TabBar 的示例
|
||||
*/
|
||||
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class TabBarDemo extends StatefulWidget {
|
||||
const TabBarDemo() : super();
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _TabBarDemo();
|
||||
}
|
||||
|
||||
/*
|
||||
* AppBar 默认的实例,有状态
|
||||
* */
|
||||
class _TabBarDemo extends State with SingleTickerProviderStateMixin {
|
||||
ScrollController _scrollViewController;
|
||||
TabController _tabController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_scrollViewController = new ScrollController();
|
||||
_tabController = new TabController(vsync: this, length: 6);// 和下面的 TabBar.tabs 数量对应
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_scrollViewController.dispose();
|
||||
_tabController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// 如果省略了 leading ,但 AppBar 在带有 Drawer 的 Scaffold 中,则会插入一个 button 以打开 Drawer。
|
||||
// 否则,如果最近的 Navigator 具有任何先前的 router ,则会插入BackButton。
|
||||
// 这种行为可以通过设置来关闭automaticallyImplyLeading 为false。在这种情况下,空的 leading widget 将导致 middle/title widget 拉伸开始。
|
||||
return new SizedBox(
|
||||
height: 500,
|
||||
child:new Scaffold(
|
||||
appBar: new AppBar( // 大量配置属性参考 SliverAppBar 示例
|
||||
title: new Text('TabBar'),
|
||||
leading: new Icon(Icons.home),
|
||||
backgroundColor: Colors.amber[1000],
|
||||
bottom: new TabBar(
|
||||
isScrollable: true,
|
||||
controller: _tabController,
|
||||
tabs: <Widget>[
|
||||
new Tab(text: "Tabs 1"),
|
||||
new Tab(text: "Tabs 2"),
|
||||
new Tab(text: "Tabs 3"),
|
||||
new Tab(text: "Tabs 4"),
|
||||
new Tab(text: "Tabs 5"),
|
||||
new Tab(text: "Tabs 6"),
|
||||
],
|
||||
),
|
||||
),
|
||||
body: new TabBarView(controller: _tabController, children: <Widget>[
|
||||
Text('TabsView 1'),
|
||||
Text('TabsView 2'),
|
||||
Text('TabsView 3'),
|
||||
Text('TabsView 4'),
|
||||
Text('TabsView 5'),
|
||||
Text('TabsView 6'),
|
||||
]),
|
||||
)
|
||||
|
||||
);
|
||||
}
|
||||
}
|
70
lib/widgets/components/Bar/TabBar/index.dart
Normal file
70
lib/widgets/components/Bar/TabBar/index.dart
Normal file
@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: sanfan.hx
|
||||
* Date: 2019/1/6
|
||||
* Time: 下午17:08
|
||||
* email: sanfan.hx@alibaba-inc.com
|
||||
* tartget: SnackBarAction 的示例
|
||||
*/
|
||||
import '../../../../common/widget_demo.dart';
|
||||
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import './demo.dart';
|
||||
|
||||
const String _Text0 = """
|
||||
### **简介**
|
||||
> SnackBarAction 来实现并行界面的横向滑动展示
|
||||
|
||||
TabBar,是材料设计中很常用的一种横向标签. 来实现并行界面的横向滑动展示,在Flutter的世界中,TabBar有着相同的作用。通常,我们会在AppBar的底部部分结合TabBarView来使用TabBar。
|
||||
|
||||
|
||||
|
||||
### **基本用法**
|
||||
|
||||
> 在容器顶部或者底部配置, TabBar组件, 横向切换视口窗口中的内容
|
||||
|
||||
|
||||
**TabBar** 有以下几项属性
|
||||
|
||||
- tabs 一般使用Tab对象,当然也可以是其他的Widget
|
||||
- controller TabController对象
|
||||
- isScrollable 是否可滚动
|
||||
- indicatorColor 指示器颜色
|
||||
- indicatorWeight 指示器厚度
|
||||
- indicatorPadding 底部指示器的Padding
|
||||
- indicator 指示器decoration,例如边框等
|
||||
- indicatorSize 指示器大小计算方式
|
||||
- labelColor 选中Tab文字颜色
|
||||
- labelStyle 选中Tab文字Style
|
||||
- unselectedLabelColor 未选中Tab中文字颜色
|
||||
- unselectedLabelStyle 未选中Tab中文字style
|
||||
|
||||
**TabBarView** 有以下几项属性
|
||||
- children tabBar中对象分别对应的视图窗口内容, children的长度通常与tabs中的tab对象长度相同
|
||||
- controller TabController对象
|
||||
""";
|
||||
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Bar/TabBar';
|
||||
|
||||
@override
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
title: 'TabBar',
|
||||
codeUrl: 'components/Bar/TabBar/index.dart',
|
||||
contentList: [
|
||||
_Text0,
|
||||
TabBarDemo()
|
||||
],
|
||||
docUrl: 'https://docs.flutter.io/flutter/material/SnackBarAction-class.html',
|
||||
);
|
||||
}
|
||||
}
|
68
lib/widgets/components/Bar/index.dart
Normal file
68
lib/widgets/components/Bar/index.dart
Normal file
@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 一晟
|
||||
* Date: 2018/12/27
|
||||
* Time: 下午2:50
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: FlatButton 的示例
|
||||
*/
|
||||
import "package:flutter/material.dart";
|
||||
import '../../../model/widget.dart';
|
||||
|
||||
import 'SliverAppBar/index.dart' as SliverAppBar;
|
||||
import 'AppBar/index.dart' as AppBar;
|
||||
import 'BottomAppBar/index.dart' as BottomAppBar;
|
||||
import 'FlexibleSpaceBar/index.dart' as FlexibleSpaceBar;
|
||||
import 'ButtonBar/index.dart' as ButtonBar;
|
||||
import 'SnackBar/index.dart' as SnackBar;
|
||||
import 'SnackBarAction/index.dart' as SnackBarAction;
|
||||
import 'TabBar/index.dart' as TabBar;
|
||||
|
||||
|
||||
List<WidgetPoint> widgetPoints = [
|
||||
WidgetPoint(
|
||||
name: 'AppBar',
|
||||
routerName: AppBar.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => AppBar.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name: 'SliverAppBar',
|
||||
routerName: SliverAppBar.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => SliverAppBar.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name: 'BottomAppBar',
|
||||
routerName: BottomAppBar.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => BottomAppBar.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name: 'FlexibleSpaceBar',
|
||||
routerName: FlexibleSpaceBar.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => FlexibleSpaceBar.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name: 'ButtonBar',
|
||||
routerName: ButtonBar.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => ButtonBar.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name: 'SnackBar',
|
||||
routerName: SnackBar.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => SnackBar.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name: 'SnackBarAction',
|
||||
routerName: SnackBarAction.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => SnackBarAction.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name: 'TabBar',
|
||||
routerName: TabBar.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => TabBar.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name: 'TabBarView',
|
||||
routerName: TabBar.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => TabBar.Demo(),
|
||||
),
|
||||
];
|
86
lib/widgets/components/Card/Card/demo.dart
Normal file
86
lib/widgets/components/Card/Card/demo.dart
Normal file
@ -0,0 +1,86 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2019/1/1
|
||||
* Time: 下午2:57
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: Card 的示例
|
||||
*/
|
||||
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/*
|
||||
* Checkbox 默认按钮的实例
|
||||
* index 当前checkbox 的索引值
|
||||
* */
|
||||
class CardFullDefault extends StatefulWidget {
|
||||
const CardFullDefault() : super();
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _CardFullDefault();
|
||||
}
|
||||
|
||||
/*
|
||||
* Card 默认的实例,有状态
|
||||
* */
|
||||
class _CardFullDefault extends State {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Card(
|
||||
// ... // 如果没有,就是不需要有状态的 StatefulWidget
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Card 默认的实例,无状态
|
||||
* */
|
||||
class CardLessDefault extends StatelessWidget {
|
||||
final widget;
|
||||
final parent;
|
||||
|
||||
const CardLessDefault([this.widget, this.parent])
|
||||
: super();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Card(
|
||||
clipBehavior:Clip.antiAlias,// 根据设置裁剪内容
|
||||
color:Colors.green, // 卡片背景颜色
|
||||
elevation:20.0, // 卡片的z坐标,控制卡片下面的阴影大小
|
||||
margin:EdgeInsets.all(20.0),
|
||||
// margin: EdgeInsetsDirectional.only(bottom: 30.0, top: 30.0, start: 30.0),// 边距
|
||||
semanticContainer:true, // 表示单个语义容器,还是false表示单个语义节点的集合,接受单个孩子,但该孩子可以是Row,Column或其他包含子级列表的widget
|
||||
// shape:new Border.all(
|
||||
// color: Colors.indigo, width: 1.0, style: BorderStyle.solid), // 卡片材质的形状,以及边框
|
||||
shape:RoundedRectangleBorder(borderRadius: new BorderRadius.circular(20.0)), // 圆角
|
||||
//borderRadius: BorderRadius.all(Radius.circular(8.0)),
|
||||
child: Column( //card里面的子控件
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
const ListTile(
|
||||
leading: Icon(Icons.access_time),
|
||||
title: Text('The Enchanted Nightingale',style: TextStyle(color: Colors.white, fontSize: 40.0)),
|
||||
subtitle: Text('Music by Julie Gable. Lyrics by Sidney Stein.',style: TextStyle(color: Colors.yellow, fontSize: 16.0)),
|
||||
contentPadding: EdgeInsets.all(20.0),// item 内容内边距
|
||||
),
|
||||
ButtonTheme.bar( // make buttons use the appropriate styles for cards
|
||||
child: ButtonBar(
|
||||
children: <Widget>[
|
||||
FlatButton(
|
||||
child: const Text('BUY TICKETS',style: TextStyle(color: Colors.black, fontSize: 14.0)),
|
||||
onPressed: () { /* ... */ },
|
||||
),
|
||||
FlatButton(
|
||||
child: const Text('LISTEN',style: TextStyle(color: Colors.black, fontSize: 14.0)),
|
||||
onPressed: () { /* ... */ },
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
74
lib/widgets/components/Card/Card/index.dart
Normal file
74
lib/widgets/components/Card/Card/index.dart
Normal file
@ -0,0 +1,74 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2019/1/1
|
||||
* Time: 下午2:56
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: Card 的示例
|
||||
*/
|
||||
import '../../../../common/widget-demo.dart';
|
||||
import '../../../../routers/application.dart';
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import './demo.dart' as CardDemo;
|
||||
|
||||
const String _Text0 =
|
||||
"""### **简介**
|
||||
> Card “卡片”
|
||||
- 卡片是用于表示一些相关信息的一张材料,例如相册,地理位置,用餐,联系方式等
|
||||
""";
|
||||
|
||||
|
||||
const String _Text1 =
|
||||
"""### **基本用法**
|
||||
> 此示例显示了创建卡片窗口组件,其中显示了相册信息和两个操作
|
||||
""";
|
||||
|
||||
const String _Text2 =
|
||||
"""### **进阶用法**
|
||||
> Card
|
||||
-
|
||||
""";
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Card/Card';
|
||||
|
||||
@override
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
title: 'Card',
|
||||
codeUrl: '${Application
|
||||
.github['widgetsURL']}componentss/Card/Card/demo.dart',
|
||||
child: allCheckboxs(context, this),
|
||||
docUrl: 'https://docs.flutter.io/flutter/material/Card-class.html',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 所有的 Card widget
|
||||
* context: 运行上下文
|
||||
* that: 指向有状态的 StatefulWidget
|
||||
*/
|
||||
Widget allCheckboxs(BuildContext context, _DemoState that) {
|
||||
return Container(
|
||||
//padding: new EdgeInsets.only(bottom: 20.0, top: 20.0, left: 0, right: 0),
|
||||
child: Column(
|
||||
//mainAxisSize: MainAxisSize.max,
|
||||
children: <Widget>[
|
||||
MarkdownBody(data: _Text0),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
MarkdownBody(data: _Text1),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
CardDemo.CardLessDefault()
|
||||
])
|
||||
);
|
||||
}
|
||||
|
20
lib/widgets/components/Card/index.dart
Normal file
20
lib/widgets/components/Card/index.dart
Normal file
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 一晟
|
||||
* Date: 2018/12/27
|
||||
* Time: 下午2:50
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: FlatButton 的示例
|
||||
*/
|
||||
import "package:flutter/material.dart";
|
||||
import '../../../model/widget.dart';
|
||||
|
||||
import 'Card/index.dart' as Card;
|
||||
|
||||
List<WidgetPoint> widgetPoints = [
|
||||
WidgetPoint(
|
||||
name: 'Card',
|
||||
routerName: Card.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => Card.Demo(),
|
||||
)
|
||||
];
|
84
lib/widgets/components/Chip/Chip/demo.dart
Normal file
84
lib/widgets/components/Chip/Chip/demo.dart
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* @Author: xiaojia.dxj
|
||||
* @Date: 2018-12-18 11:40:57
|
||||
* @Last Modified by: xiaojia.dxj
|
||||
* @Last Modified time: 2018-12-20 15:03:18
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ChipDemo extends StatefulWidget {
|
||||
_ChipDemoState createState() => _ChipDemoState();
|
||||
}
|
||||
|
||||
class _ChipDemoState extends State<ChipDemo> {
|
||||
String dec='点击回收';
|
||||
int count=0;
|
||||
_modifty(){
|
||||
setState(() {
|
||||
dec='delete success: $count';
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: Chip(
|
||||
padding: EdgeInsets.only(right: 100.0,),
|
||||
//标签前面的小widget
|
||||
avatar: CircleAvatar(
|
||||
backgroundColor: Colors.red.shade200,
|
||||
child: Text('A',style: TextStyle(color: Colors.white),),
|
||||
|
||||
),
|
||||
label: Text('pai mai ',style: TextStyle(color: Colors.white,fontSize: 18.0),),
|
||||
backgroundColor: Colors.red.shade100,
|
||||
labelPadding: EdgeInsets.all(6.0),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
|
||||
height: 100.0,
|
||||
child: Chip(
|
||||
//头像
|
||||
avatar: CircleAvatar(
|
||||
child: Icon(Icons.account_circle,color: Colors.red.shade200,),
|
||||
backgroundColor:Colors.white,
|
||||
|
||||
),
|
||||
//设置widget背景颜色
|
||||
backgroundColor: Colors.red.shade100,
|
||||
/**剪辑窗口widget内容
|
||||
* antiAlias:剪辑具有抗锯齿功能,它比antiAliasWithSaveLayer快得多,但比hardEdge慢。
|
||||
antiAliasWithSaveLayer:立即剪辑具有抗锯齿,并且可以分配屏幕外缓冲区,后续涂料都在该缓冲区完成,然后再进行修剪和合成
|
||||
*/
|
||||
clipBehavior: Clip.antiAlias,
|
||||
|
||||
//设置padding值
|
||||
labelPadding: EdgeInsets.all(8.0),
|
||||
label: Text(dec),
|
||||
//设置onDeleted时候显示的图标
|
||||
deleteIcon: Icon(Icons.delete,color: Colors.white,size: 20.0,),
|
||||
onDeleted: (){
|
||||
count++;
|
||||
_modifty();
|
||||
},
|
||||
deleteButtonTooltipMessage: '删除',
|
||||
deleteIconColor: Colors.blueGrey.shade100,
|
||||
//将最小点击目标大小扩展到48*48px
|
||||
materialTapTargetSize: MaterialTapTargetSize.padded,
|
||||
padding: EdgeInsets.all(2.0),
|
||||
//修改字体格式
|
||||
labelStyle: TextStyle(fontWeight: FontWeight.bold),
|
||||
// shape: _MyBorder(),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
41
lib/widgets/components/Chip/Chip/index.dart
Normal file
41
lib/widgets/components/Chip/Chip/index.dart
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* @Author: xiaojia.dxj
|
||||
* @Date: 2018-12-18 11:40:57
|
||||
* @Last Modified by: xiaojia.dxj
|
||||
* @Last Modified time: 2018-12-18 15:13:23
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../common/widget_demo.dart';
|
||||
import 'demo.dart';
|
||||
|
||||
const String content0 = '''
|
||||
### **简介**
|
||||
> chip是表示属性,文本,实体或动作的元素
|
||||
- 需要在Material wedige 中。
|
||||
''';
|
||||
const String content1 = '''
|
||||
### **基本用法**
|
||||
- 需要Material widget.
|
||||
- 这个label和clipBehavior参数不能为空
|
||||
''';
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Chip/Chip';
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
contentList: [
|
||||
content0,
|
||||
content1,
|
||||
ChipDemo(),
|
||||
],
|
||||
codeUrl: 'components/Chip/Chip/demo.dart',
|
||||
docUrl:
|
||||
'https://docs.flutter.io/flutter/material/Chip-class.html',
|
||||
title: 'Chip');
|
||||
}
|
||||
}
|
60
lib/widgets/components/Chip/ChipTheme/demo.dart
Normal file
60
lib/widgets/components/Chip/ChipTheme/demo.dart
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* @Author: xiaojia.dxj
|
||||
* @Date: 2018-12-18 15:14:10
|
||||
* @Last Modified by: xiaojia.dxj
|
||||
* @Last Modified time: 2018-12-18 19:15:25
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ChipThemeDemo extends StatefulWidget {
|
||||
_ChipThemeDemoState createState() => _ChipThemeDemoState();
|
||||
}
|
||||
|
||||
class _ChipThemeDemoState extends State<ChipThemeDemo> {
|
||||
Color _color = Colors.red;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChipTheme(
|
||||
data: ChipTheme.of(context).copyWith(backgroundColor:Colors.red.shade800 ),
|
||||
child: ChoiceChip(
|
||||
padding: EdgeInsets.only(left: 100.0,right: 100.0,top: 10.0,bottom: 10.0),
|
||||
label: Text('down'),
|
||||
labelStyle: TextStyle(color: Colors.white),
|
||||
onSelected: (bool value) {
|
||||
setState(() {
|
||||
_color = value ? Colors.lightBlue : Colors.red;
|
||||
});
|
||||
},
|
||||
selected: _color == Colors.lightBlue,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Widget build(BuildContext context) {
|
||||
|
||||
// return Container(
|
||||
// child: ChipTheme(
|
||||
// data: ChipThemeData(
|
||||
// backgroundColor: Colors.red.shade500,
|
||||
// //描述颜色对比度(暗,亮,设置固定值)
|
||||
// brightness : Brightness.dark,
|
||||
// deleteIconColor: Colors.red.shade200,
|
||||
// //背景颜色,表示它被禁用
|
||||
// disabledColor: Colors.grey.shade50,
|
||||
// labelPadding: EdgeInsets.all(10.0),
|
||||
// labelStyle: TextStyle(fontSize: 15.0,fontStyle: FontStyle.italic),
|
||||
// padding: EdgeInsets.all(2.0),
|
||||
// //用于另一种chip widget 标签样式
|
||||
// secondaryLabelStyle: TextStyle(fontSize: 20.0,fontStyle: FontStyle.normal),
|
||||
// selectedColor: Colors.yellow,
|
||||
// //表示已经选中度颜色
|
||||
// secondarySelectedColor: Colors.black
|
||||
// // shape:
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
|
||||
|
||||
// }
|
42
lib/widgets/components/Chip/ChipTheme/index.dart
Normal file
42
lib/widgets/components/Chip/ChipTheme/index.dart
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* @Author: xiaojia.dxj
|
||||
* @Date: 2018-12-18 15:14:03
|
||||
* @Last Modified by: xiaojia.dxj
|
||||
* @Last Modified time: 2018-12-18 15:14:03
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../common/widget_demo.dart';
|
||||
import 'demo.dart';
|
||||
|
||||
const String content0 = '''
|
||||
### **简介**
|
||||
> 基于 RawChip-based widgets,如chip,inputChip,ChoiceChip,FilterChip等
|
||||
- chipTheme描述了应用它的chip的颜色,形状和文本样式
|
||||
|
||||
''';
|
||||
const String content1 = '''
|
||||
### **基本用法**
|
||||
- 可通过chipTheme.of获取当前主题的ChipThemeData对象
|
||||
- 当widget使用ChipTheme.of时,如果主题稍后更改,则会自动重建。
|
||||
''';
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Chip/ChipTheme';
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
contentList: [
|
||||
content0,
|
||||
content1,
|
||||
ChipThemeDemo(),
|
||||
],
|
||||
codeUrl: 'components/Chip/ChipTheme/demo.dart',
|
||||
docUrl:
|
||||
'https://docs.flutter.io/flutter/material/ChipTheme-class.html',
|
||||
title: 'ChipTheme');
|
||||
}
|
||||
}
|
38
lib/widgets/components/Chip/ChipThemeData/demo.dart
Normal file
38
lib/widgets/components/Chip/ChipThemeData/demo.dart
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* @Author: xiaojia.dxj
|
||||
* @Date: 2018-12-18 15:14:10
|
||||
* @Last Modified by: xiaojia.dxj
|
||||
* @Last Modified time: 2018-12-18 19:39:41
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ChipThemeDemo extends StatefulWidget {
|
||||
_ChipThemeDemoState createState() => _ChipThemeDemoState();
|
||||
}
|
||||
|
||||
class _ChipThemeDemoState extends State<ChipThemeDemo> {
|
||||
Color _color = Colors.red;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChipTheme(
|
||||
data: ChipThemeData.fromDefaults(
|
||||
// brightness: Brightness.dark,
|
||||
labelStyle: TextStyle(fontSize: 15.0),
|
||||
primaryColor: Colors.red,secondaryColor: Colors.red.shade800),
|
||||
child: ChoiceChip(
|
||||
padding: EdgeInsets.only(left: 100.0,right: 100.0,top: 10.0,bottom: 10.0),
|
||||
label: Text('down'),
|
||||
onSelected: (bool value) {
|
||||
setState(() {
|
||||
_color = value ? Colors.black : Colors.red;
|
||||
});
|
||||
},
|
||||
selected: _color == Colors.black,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
42
lib/widgets/components/Chip/ChipThemeData/index.dart
Normal file
42
lib/widgets/components/Chip/ChipThemeData/index.dart
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* @Author: xiaojia.dxj
|
||||
* @Date: 2018-12-18 15:14:03
|
||||
* @Last Modified by: xiaojia.dxj
|
||||
* @Last Modified time: 2018-12-18 17:38:56
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../common/widget_demo.dart';
|
||||
import 'demo.dart';
|
||||
|
||||
const String content0 = '''
|
||||
### **简介**
|
||||
> 保存chip主题的颜色,形状和文本样式
|
||||
- 使用它配置chipTheme widget,或者为Theme widget小部件设置 ThemeData.chipTheme。
|
||||
|
||||
''';
|
||||
const String content1 = '''
|
||||
### **基本用法**
|
||||
- 创建ChipThemeData最简单的方法是使用copyWith您从得到一个ChipTheme.of,
|
||||
或创建一个全新的一个具有 ChipThemeData..fromDefaults。。
|
||||
''';
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Chip/ChipThemeData';
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
contentList: [
|
||||
content0,
|
||||
content1,
|
||||
ChipThemeDemo(),
|
||||
],
|
||||
codeUrl: 'components/Chip/ChipThemeData/demo.dart',
|
||||
docUrl:
|
||||
'https://docs.flutter.io/flutter/material/ChipThemeData-class.html',
|
||||
title: 'ChipThemeData');
|
||||
}
|
||||
}
|
62
lib/widgets/components/Chip/ChoiceChip/demo.dart
Normal file
62
lib/widgets/components/Chip/ChoiceChip/demo.dart
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* @Author: xiaojia.dxj
|
||||
* @Date: 2018-12-19 15:13:24
|
||||
* @Last Modified by: xiaojia.dxj
|
||||
* @Last Modified time: 2018-12-20 19:32:10
|
||||
*/
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ChoiceChipDemo extends StatefulWidget {
|
||||
_ChoiceChipDemoState createState() => _ChoiceChipDemoState();
|
||||
}
|
||||
|
||||
class _ChoiceChipDemoState extends State<ChoiceChipDemo> {
|
||||
String _selected = '';
|
||||
|
||||
List<String> _sub=<String>[
|
||||
'java','web','android'
|
||||
];
|
||||
|
||||
Iterable<Widget> get actorWidgets sync*{
|
||||
for(String choiceSub in _sub){
|
||||
yield Padding(
|
||||
padding:EdgeInsets.all(15.0) ,
|
||||
child: ChoiceChip(
|
||||
// avatar: Icon(Icons.access_alarm,size: 20.0,color: Colors.white,),
|
||||
//未选定的时候背景
|
||||
backgroundColor:Colors.red,
|
||||
//被禁用得时候背景
|
||||
disabledColor: Colors.blue,
|
||||
label: Text(choiceSub),
|
||||
labelStyle: TextStyle(fontWeight: FontWeight.w200,fontSize: 15.0),
|
||||
labelPadding: EdgeInsets.only(left: 20.0,right: 20.0),
|
||||
|
||||
materialTapTargetSize: MaterialTapTargetSize.padded,
|
||||
onSelected: (bool value) {
|
||||
setState(() {
|
||||
_selected = value ? choiceSub : 'Colors.red';
|
||||
});
|
||||
},
|
||||
selected: _selected == choiceSub,)
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Wrap(
|
||||
children: actorWidgets.toList(),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
41
lib/widgets/components/Chip/ChoiceChip/index.dart
Normal file
41
lib/widgets/components/Chip/ChoiceChip/index.dart
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* @Author: xiaojia.dxj
|
||||
* @Date: 2018-12-19 15:13:29
|
||||
* @Last Modified by: xiaojia.dxj
|
||||
* @Last Modified time: 2018-12-21 10:22:57
|
||||
*/
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../common/widget_demo.dart';
|
||||
import 'demo.dart';
|
||||
|
||||
const String content0 = '''
|
||||
### **简介**
|
||||
> 允许从一组选项中进行单一的选择
|
||||
- ChoiceChip包含相关的描述性文本或者类别
|
||||
|
||||
''';
|
||||
const String content1 = '''
|
||||
### **基本用法**
|
||||
- onSelected : 选择或者取消选择状态间切换调用
|
||||
''';
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Chip/ChoiceChip';
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
contentList: [
|
||||
content0,
|
||||
content1,
|
||||
ChoiceChipDemo(),
|
||||
],
|
||||
codeUrl: 'components/Chip/ChoiceChip/demo.dart',
|
||||
docUrl:'https://docs.flutter.io/flutter/material/ChoiceChip-class.html',
|
||||
title: 'ChoiceChip');
|
||||
}
|
||||
}
|
69
lib/widgets/components/Chip/FilterChip/demo.dart
Normal file
69
lib/widgets/components/Chip/FilterChip/demo.dart
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* @Author: xiaojia.dxj
|
||||
* @Date: 2018-12-20 10:19:46
|
||||
* @Last Modified by: xiaojia.dxj
|
||||
* @Last Modified time: 2018-12-20 14:09:31
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class FilterChipDemo extends StatefulWidget {
|
||||
_FilterChipDemoState createState() => _FilterChipDemoState();
|
||||
}
|
||||
|
||||
class ActorFilerEntry{
|
||||
final String name;
|
||||
final String initials;
|
||||
const ActorFilerEntry(this.name,this.initials);
|
||||
}
|
||||
|
||||
|
||||
class _FilterChipDemoState extends State<FilterChipDemo> {
|
||||
final List<ActorFilerEntry> _list=<ActorFilerEntry>[
|
||||
const ActorFilerEntry('android', 'ad'),
|
||||
const ActorFilerEntry('java', 'ja'),
|
||||
const ActorFilerEntry('php', 'ph'),
|
||||
const ActorFilerEntry('web', 'wb'),
|
||||
];
|
||||
|
||||
List<String> _filters=<String>[];
|
||||
Iterable<Widget> get actorWidgets sync*{
|
||||
for(ActorFilerEntry actor in _list){
|
||||
yield Padding(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
child: FilterChip(
|
||||
// avatar: CircleAvatar(child: Text(actor.initials),),
|
||||
label: Text(actor.name),
|
||||
selected: _filters.contains(actor.name),
|
||||
onSelected: (bool value){
|
||||
setState(() {
|
||||
if(value){
|
||||
_filters.add(actor.name);
|
||||
}else{
|
||||
_filters.retainWhere((String name){
|
||||
return name==actor.name;
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Wrap(
|
||||
children: actorWidgets.toList(),
|
||||
),
|
||||
Text('look for :${_filters.join(',')}')
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
40
lib/widgets/components/Chip/FilterChip/index.dart
Normal file
40
lib/widgets/components/Chip/FilterChip/index.dart
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* @Author: xiaojia.dxj
|
||||
* @Date: 2018-12-20 10:19:55
|
||||
* @Last Modified by: xiaojia.dxj
|
||||
* @Last Modified time: 2018-12-21 10:25:22
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../common/widget_demo.dart';
|
||||
import 'demo.dart';
|
||||
|
||||
const String content0 = '''
|
||||
### **简介**
|
||||
> 通过使用标签或者描述性词语来过滤内容
|
||||
- FilterChip是checkbox或switch widget 的替换品。
|
||||
|
||||
''';
|
||||
const String content1 = '''
|
||||
### **基本用法**
|
||||
''';
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Chip/FilterChip';
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
contentList: [
|
||||
content0,
|
||||
content1,
|
||||
FilterChipDemo(),
|
||||
],
|
||||
codeUrl: 'components/Chip/FilterChip/demo.dart',
|
||||
docUrl:
|
||||
'https://docs.flutter.io/flutter/material/FilterChip-class.html',
|
||||
title: 'FilterChip');
|
||||
}
|
||||
}
|
69
lib/widgets/components/Chip/RawChip/demo.dart
Normal file
69
lib/widgets/components/Chip/RawChip/demo.dart
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* @Author: xiaojia.dxj
|
||||
* @Date: 2018-12-20 20:30:36
|
||||
* @Last Modified by: xiaojia.dxj
|
||||
* @Last Modified time: 2018-12-21 11:23:21
|
||||
*/
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
||||
class FilterChipDemo extends StatefulWidget {
|
||||
_FilterChipDemoState createState() => _FilterChipDemoState();
|
||||
}
|
||||
|
||||
class InputEntry{
|
||||
final String name;
|
||||
final String initials;
|
||||
const InputEntry(this.name,this.initials);
|
||||
}
|
||||
|
||||
class _FilterChipDemoState extends State<FilterChipDemo> {
|
||||
|
||||
final List<InputEntry> _lists=<InputEntry>[
|
||||
const InputEntry('android', 'A'),
|
||||
const InputEntry('java', 'J'),
|
||||
const InputEntry('php', 'P'),
|
||||
const InputEntry('web', 'W'),
|
||||
];
|
||||
|
||||
List<String> _inputs=<String>[];
|
||||
Iterable<Widget> get RawChipWidget sync*{
|
||||
for(InputEntry value in _lists){
|
||||
yield Padding(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
child: RawChip(
|
||||
avatar: CircleAvatar(
|
||||
backgroundColor: Colors.redAccent.shade400,
|
||||
child: Text(value.initials),
|
||||
),
|
||||
label: Text(value.name),
|
||||
onDeleted: (){
|
||||
// _inputs.add(value.name);
|
||||
setState(() {
|
||||
_lists.remove(value);
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
Wrap(
|
||||
children: RawChipWidget.toList(),
|
||||
),
|
||||
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
47
lib/widgets/components/Chip/RawChip/index.dart
Normal file
47
lib/widgets/components/Chip/RawChip/index.dart
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* @Author: xiaojia.dxj
|
||||
* @Date: 2018-12-20 20:30:41
|
||||
* @Last Modified by: xiaojia.dxj
|
||||
* @Last Modified time: 2018-12-21 11:35:51
|
||||
*/
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../common/widget_demo.dart';
|
||||
import 'demo.dart';
|
||||
|
||||
const String content0 = '''
|
||||
### **简介**
|
||||
> 所有chip widget类型的基础,集合所有功能,我们通常不是直接使用它,而是根据自己需要选择chi, 比如:
|
||||
- chip ,一个简单的芯片,只能显示信息,并被删除
|
||||
- inputChip,以紧凑的形式表现复杂的信息,例如:实体(人,地点,或者事物)或者会话文本
|
||||
- choiceChip,允许从一组选项中进行单一的选择
|
||||
- FilterChip,使用标签或描述作为过滤内容的方式
|
||||
|
||||
|
||||
''';
|
||||
const String content1 = '''
|
||||
### **基本用法**
|
||||
- inputChip可以通过设置进行选择onSelected,通过设置onDeleted可以删除,并且可以通过OnPressed表现按压效果
|
||||
- inputChip 有一个前导图标和尾随图标,填充颜色可以订制
|
||||
- inputChip 可以和其他UI元素搭配使用,比如:wrap,ListView(scrollDirection为Axis.horizontal)
|
||||
''';
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Chip/RawChip';
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
contentList: [
|
||||
content0,
|
||||
content1,
|
||||
FilterChipDemo(),
|
||||
],
|
||||
codeUrl: 'components/Chip/RawChip/demo.dart',
|
||||
docUrl:'https://docs.flutter.io/flutter/material/RawChip-class.html',
|
||||
title: 'RawChip');
|
||||
}
|
||||
}
|
49
lib/widgets/components/Chip/index.dart
Normal file
49
lib/widgets/components/Chip/index.dart
Normal file
@ -0,0 +1,49 @@
|
||||
import "package:flutter/material.dart";
|
||||
import '../../../model/widget.dart';
|
||||
|
||||
import 'Chip/index.dart' as Chip;
|
||||
import 'ChipTheme/index.dart' as ChipTheme;
|
||||
import 'ChipThemeData/index.dart' as ChipThemeData;
|
||||
import 'ChoiceChip/index.dart' as ChoiceChip;
|
||||
import 'FilterChip/index.dart' as FilterChip;
|
||||
import 'InputChip/index.dart' as InputChip;
|
||||
import 'RawChip/index.dart' as RawChip;
|
||||
|
||||
|
||||
List<WidgetPoint> widgetPoints = [
|
||||
WidgetPoint(
|
||||
name: 'Chip',
|
||||
routerName: Chip.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => Chip.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name: 'ChipTheme',
|
||||
routerName: ChipTheme.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => ChipTheme.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name: 'ChipThemeData',
|
||||
routerName: ChipThemeData.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => ChipThemeData.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name: 'ChoiceChip',
|
||||
routerName: ChoiceChip.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => ChoiceChip.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name: 'FilterChip',
|
||||
routerName: FilterChip.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => FilterChip.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name: 'InputChip',
|
||||
routerName: InputChip.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => InputChip.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name: 'RawChip',
|
||||
routerName: RawChip.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => RawChip.Demo(),
|
||||
),
|
||||
];
|
77
lib/widgets/components/Chip/inputChip/demo.dart
Normal file
77
lib/widgets/components/Chip/inputChip/demo.dart
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* @Author: xiaojia.dxj
|
||||
* @Date: 2018-12-20 13:32:22
|
||||
* @Last Modified by: xiaojia.dxj
|
||||
* @Last Modified time: 2018-12-21 11:31:12
|
||||
*/
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
||||
class FilterChipDemo extends StatefulWidget {
|
||||
_FilterChipDemoState createState() => _FilterChipDemoState();
|
||||
}
|
||||
|
||||
class InputEntry{
|
||||
final String name;
|
||||
final String initials;
|
||||
const InputEntry(this.name,this.initials);
|
||||
|
||||
}
|
||||
|
||||
class _FilterChipDemoState extends State<FilterChipDemo> {
|
||||
|
||||
final List<InputEntry> _lists=<InputEntry>[
|
||||
const InputEntry('android', 'A'),
|
||||
const InputEntry('java', 'J'),
|
||||
const InputEntry('php', 'P'),
|
||||
const InputEntry('web', 'W'),
|
||||
];
|
||||
|
||||
List<InputEntry> _inputLists=<InputEntry>[];
|
||||
Iterable<Widget> get inputWidget sync*{
|
||||
for(InputEntry value in _lists){
|
||||
_inputLists.add(value);
|
||||
yield Padding(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
child: InputChip(
|
||||
avatar: CircleAvatar(
|
||||
backgroundColor: Colors.redAccent.shade400,
|
||||
child: Text(value.initials),
|
||||
),
|
||||
label: Text(value.name),
|
||||
onDeleted: (){
|
||||
setState(() {
|
||||
_lists.remove(value);
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
Wrap(
|
||||
children: inputWidget.toList(),
|
||||
),
|
||||
// InputChip(
|
||||
// label: Text('刷新'),
|
||||
// onSelected: (bool value){
|
||||
|
||||
// },
|
||||
// )
|
||||
],
|
||||
|
||||
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
43
lib/widgets/components/Chip/inputChip/index.dart
Normal file
43
lib/widgets/components/Chip/inputChip/index.dart
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* @Author: xiaojia.dxj
|
||||
* @Date: 2018-12-20 13:32:15
|
||||
* @Last Modified by: xiaojia.dxj
|
||||
* @Last Modified time: 2018-12-21 10:42:05
|
||||
*/
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../common/widget_demo.dart';
|
||||
import 'demo.dart';
|
||||
|
||||
const String content0 = '''
|
||||
### **简介**
|
||||
> 输入型chip
|
||||
- 以紧凑的形式表现复杂的信息,例如:实体(人,地点,或者事物)或者会话文本
|
||||
|
||||
''';
|
||||
const String content1 = '''
|
||||
### **基本用法**
|
||||
- inputChip可以通过设置进行选择onSelected,通过设置onDeleted可以删除,并且可以通过OnPressed表现按压效果
|
||||
- inputChip 有一个前导图标和尾随图标,填充颜色可以订制
|
||||
- inputChip 可以和其他UI元素搭配使用,比如:wrap,ListView(scrollDirection为Axis.horizontal)
|
||||
''';
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Chip/InputChip';
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
contentList: [
|
||||
content0,
|
||||
content1,
|
||||
FilterChipDemo(),
|
||||
],
|
||||
codeUrl: 'components/Chip/FilterChip/demo.dart',
|
||||
docUrl:'https://docs.flutter.io/flutter/material/InputChip-class.html',
|
||||
title: 'InputChip');
|
||||
}
|
||||
}
|
52
lib/widgets/components/Dialog/AboutDialog/demo.dart
Normal file
52
lib/widgets/components/Dialog/AboutDialog/demo.dart
Normal file
@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 三帆
|
||||
* Date: 07/01/2019
|
||||
* Time: 10:31
|
||||
* email: sanfan.hx@alibaba-inc.com
|
||||
* tartget: xxx
|
||||
*/
|
||||
|
||||
import 'dart:math';
|
||||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
||||
class AboutDialogDemo extends StatefulWidget {
|
||||
_Demo createState() => _Demo();
|
||||
}
|
||||
|
||||
class _Demo extends State<AboutDialogDemo> {
|
||||
|
||||
void showAlertDialog(BuildContext context) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (_) => new AboutDialog(
|
||||
applicationName: '名称',
|
||||
applicationIcon: new Icon(Icons.ac_unit),
|
||||
applicationVersion: 'V1.0',
|
||||
children: <Widget>[
|
||||
Text('我是一个关于的dialog')
|
||||
]
|
||||
));
|
||||
}
|
||||
Widget build(BuildContext context) {
|
||||
return new RaisedButton(
|
||||
padding: new EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 10.0),
|
||||
//padding
|
||||
child: new Text(
|
||||
'show aboutDialog',
|
||||
style: new TextStyle(
|
||||
fontSize: 18.0, //textsize
|
||||
color: Colors.white, // textcolor
|
||||
),
|
||||
),
|
||||
color: Theme.of(context).accentColor,
|
||||
elevation: 4.0,
|
||||
//shadow
|
||||
splashColor: Colors.blueGrey,
|
||||
onPressed: () {
|
||||
showAlertDialog(context);
|
||||
});
|
||||
}
|
||||
}
|
46
lib/widgets/components/Dialog/AboutDialog/index.dart
Normal file
46
lib/widgets/components/Dialog/AboutDialog/index.dart
Normal file
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 三帆
|
||||
* Date: 07/01/2019
|
||||
* Time: 10:26
|
||||
* email: sanfan.hx@alibaba-inc.com
|
||||
* tartget: xxx
|
||||
*/
|
||||
import '../../../../common/widget_demo.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'demo.dart';
|
||||
|
||||
const String _Text0 = """
|
||||
### **简介**
|
||||
> AboutDialog 通常用于传递企业或者app的官方信息
|
||||
|
||||
|
||||
|
||||
### **基本用法**
|
||||
|
||||
> 通常作为子窗口小部件传递给showDialog,后者显示对话框。
|
||||
|
||||
""";
|
||||
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Dialog/AboutDialog';
|
||||
|
||||
@override
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
title: 'AlertDialog',
|
||||
codeUrl: 'components/Dialog/AboutDialog/demo.dart',
|
||||
contentList: [
|
||||
_Text0,
|
||||
AboutDialogDemo()
|
||||
],
|
||||
docUrl: 'https://docs.flutter.io/flutter/material/AboutDialog-class.html',
|
||||
);
|
||||
}
|
||||
}
|
145
lib/widgets/components/Dialog/AlertDialog/demo.dart
Normal file
145
lib/widgets/components/Dialog/AlertDialog/demo.dart
Normal file
@ -0,0 +1,145 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 三帆
|
||||
* Date: 07/01/2019
|
||||
* Time: 10:31
|
||||
* email: sanfan.hx@alibaba-inc.com
|
||||
* tartget: xxx
|
||||
*/
|
||||
|
||||
import 'dart:math';
|
||||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
||||
class AlertDialogDemo extends StatefulWidget {
|
||||
_Demo createState() => _Demo();
|
||||
}
|
||||
|
||||
class _Demo extends State<AlertDialogDemo> {
|
||||
|
||||
void showAlertDialog(BuildContext context) {
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
barrierDismissible: false, // user must tap button!
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text('title'),
|
||||
content: SingleChildScrollView(
|
||||
child: ListBody(
|
||||
children: <Widget>[
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
Text('too long~~~'),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
actions: <Widget>[
|
||||
FlatButton(
|
||||
child: Text('关闭'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
Widget build(BuildContext context) {
|
||||
return new RaisedButton(
|
||||
padding: new EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 10.0),
|
||||
//padding
|
||||
child: new Text(
|
||||
'点我显示 AlertDialog',
|
||||
style: new TextStyle(
|
||||
fontSize: 18.0, //textsize
|
||||
color: Colors.white, // textcolor
|
||||
),
|
||||
),
|
||||
color: Theme.of(context).accentColor,
|
||||
elevation: 4.0,
|
||||
//shadow
|
||||
splashColor: Colors.blueGrey,
|
||||
onPressed: () {
|
||||
showAlertDialog(context);
|
||||
});
|
||||
}
|
||||
}
|
50
lib/widgets/components/Dialog/AlertDialog/index.dart
Normal file
50
lib/widgets/components/Dialog/AlertDialog/index.dart
Normal file
@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 三帆
|
||||
* Date: 07/01/2019
|
||||
* Time: 10:26
|
||||
* email: sanfan.hx@alibaba-inc.com
|
||||
* tartget: xxx
|
||||
*/
|
||||
import '../../../../common/widget_demo.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'demo.dart';
|
||||
|
||||
const String _Text0 = """
|
||||
### **简介**
|
||||
> AlertDialog 向用户传递信息的弹出层。
|
||||
|
||||
|
||||
|
||||
### **基本用法**
|
||||
|
||||
> 通常作为子窗口小部件传递给showDialog,后者显示对话框。
|
||||
|
||||
当**AlertDialog**的的元素过多过长时, 请优先考虑**SingleChildScrollView** 用来避免内容溢出
|
||||
|
||||
|
||||
|
||||
""";
|
||||
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Dialog/AlertDialog';
|
||||
|
||||
@override
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
title: 'AlertDialog',
|
||||
codeUrl: 'components/Dialog/AlertDialog/demo.dart',
|
||||
contentList: [
|
||||
_Text0,
|
||||
AlertDialogDemo()
|
||||
],
|
||||
docUrl: 'https://docs.flutter.io/flutter/material/AlertDialog-class.html',
|
||||
);
|
||||
}
|
||||
}
|
107
lib/widgets/components/Dialog/Dialog/demo.dart
Normal file
107
lib/widgets/components/Dialog/Dialog/demo.dart
Normal file
@ -0,0 +1,107 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 三帆
|
||||
* Date: 07/01/2019
|
||||
* Time: 10:31
|
||||
* email: sanfan.hx@alibaba-inc.com
|
||||
* tartget: xxx
|
||||
*/
|
||||
|
||||
import 'dart:math';
|
||||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
||||
class DialogDemo extends StatefulWidget {
|
||||
_Demo createState() => _Demo();
|
||||
}
|
||||
|
||||
class _Demo extends State<DialogDemo> {
|
||||
|
||||
void showAlertDialog(BuildContext context) {
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
barrierDismissible: false, // user must tap button!
|
||||
builder: (BuildContext context) {
|
||||
return Dialog(
|
||||
child: Text("我是一个Dialog"),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
Widget build(BuildContext context) {
|
||||
return new RaisedButton(
|
||||
padding: new EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 10.0),
|
||||
//padding
|
||||
child: new Text(
|
||||
'点我显示 Dialog',
|
||||
style: new TextStyle(
|
||||
fontSize: 18.0, //textsize
|
||||
color: Colors.white, // textcolor
|
||||
),
|
||||
),
|
||||
color: Theme.of(context).accentColor,
|
||||
elevation: 4.0,
|
||||
//shadow
|
||||
splashColor: Colors.blueGrey,
|
||||
onPressed: () {
|
||||
showAlertDialog(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class DialogMoreDemo extends StatefulWidget {
|
||||
_DialogMoreDemo createState() => _DialogMoreDemo();
|
||||
}
|
||||
|
||||
class _DialogMoreDemo extends State<DialogMoreDemo> {
|
||||
int value = 0;
|
||||
void showCommonDialog(BuildContext context) {
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
barrierDismissible: false, // user must tap button!
|
||||
builder: (context) {
|
||||
return StatefulBuilder(
|
||||
builder: (context, state) {
|
||||
return Dialog(
|
||||
child: RaisedButton(
|
||||
onPressed: () {
|
||||
print("print $value");
|
||||
state(() {
|
||||
value += 1;
|
||||
});
|
||||
},
|
||||
child: Text("我是一个Dialog, 点我更新value: ${value}"),
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
Widget build(BuildContext context) {
|
||||
return new Column(
|
||||
children: <Widget>[
|
||||
new RaisedButton(
|
||||
padding: new EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 10.0),
|
||||
//padding
|
||||
child: new Text(
|
||||
'点我显示Dialog',
|
||||
style: new TextStyle(
|
||||
fontSize: 18.0, //textsize
|
||||
color: Colors.white, // textcolor
|
||||
),
|
||||
),
|
||||
color: Theme.of(context).accentColor,
|
||||
elevation: 4.0,
|
||||
//shadow
|
||||
splashColor: Colors.blueGrey,
|
||||
onPressed: () {
|
||||
showCommonDialog(context);
|
||||
}
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
59
lib/widgets/components/Dialog/Dialog/index.dart
Normal file
59
lib/widgets/components/Dialog/Dialog/index.dart
Normal file
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 三帆
|
||||
* Date: 07/01/2019
|
||||
* Time: 10:26
|
||||
* email: sanfan.hx@alibaba-inc.com
|
||||
* tartget: xxx
|
||||
*/
|
||||
import '../../../../common/widget_demo.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'demo.dart';
|
||||
|
||||
const String _Text0 = """
|
||||
### **简介**
|
||||
> AlertDialog 向用户传递信息的弹出层。
|
||||
|
||||
这个组件没有任何可操作的选项. 相比使用这个组件, 通常我们更喜欢使用 **AlertDialog**或者**SimpleDialog**
|
||||
|
||||
|
||||
|
||||
### **基本用法**
|
||||
|
||||
> 通常作为子窗口小部件传递给showDialog,后者显示对话框。
|
||||
|
||||
|
||||
""";
|
||||
|
||||
const String _Text1 = """
|
||||
### **进阶用法**
|
||||
|
||||
> 犹豫当前组件没有任何可选项目, 我们可以通过自定义样式, 去完成自己想要的各种样式的弹框, 满足我们的个性化需求
|
||||
|
||||
注意事项: 当前弹出的dialog并非是一个单纯的组件, 而是一个新路由界面, 如果我想通过操作dialog中的内容, 直接使用setState触发的是原界面中的状态
|
||||
""";
|
||||
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Dialog/Dialog';
|
||||
|
||||
@override
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
title: 'Dialog',
|
||||
codeUrl: 'components/Dialog/Dialog/demo.dart',
|
||||
contentList: [
|
||||
_Text0,
|
||||
DialogDemo(),
|
||||
_Text1,
|
||||
DialogMoreDemo()
|
||||
],
|
||||
docUrl: 'https://docs.flutter.io/flutter/material/Dialog-class.html',
|
||||
);
|
||||
}
|
||||
}
|
65
lib/widgets/components/Dialog/SimpleDialog/demo.dart
Normal file
65
lib/widgets/components/Dialog/SimpleDialog/demo.dart
Normal file
@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 三帆
|
||||
* Date: 07/01/2019
|
||||
* Time: 10:31
|
||||
* email: sanfan.hx@alibaba-inc.com
|
||||
* tartget: xxx
|
||||
*/
|
||||
|
||||
import 'dart:math';
|
||||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
||||
class SimpleDialogDemo extends StatefulWidget {
|
||||
_Demo createState() => _Demo();
|
||||
}
|
||||
|
||||
class _Demo extends State<SimpleDialogDemo> {
|
||||
|
||||
void showAlertDialog(BuildContext context) {
|
||||
showDialog<Null>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return new SimpleDialog(
|
||||
title: new Text('选择'),
|
||||
children: <Widget>[
|
||||
new SimpleDialogOption(
|
||||
child: new Text('选项 1'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
new SimpleDialogOption(
|
||||
child: new Text('选项 2'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
Widget build(BuildContext context) {
|
||||
return new RaisedButton(
|
||||
padding: new EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 10.0),
|
||||
//padding
|
||||
child: new Text(
|
||||
'show SimpleDialog',
|
||||
style: new TextStyle(
|
||||
fontSize: 18.0, //textsize
|
||||
color: Colors.white, // textcolor
|
||||
),
|
||||
),
|
||||
color: Theme.of(context).accentColor,
|
||||
elevation: 4.0,
|
||||
//shadow
|
||||
splashColor: Colors.blueGrey,
|
||||
onPressed: () {
|
||||
showAlertDialog(context);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
46
lib/widgets/components/Dialog/SimpleDialog/index.dart
Normal file
46
lib/widgets/components/Dialog/SimpleDialog/index.dart
Normal file
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 三帆
|
||||
* Date: 07/01/2019
|
||||
* Time: 10:26
|
||||
* email: sanfan.hx@alibaba-inc.com
|
||||
* tartget: xxx
|
||||
*/
|
||||
import '../../../../common/widget_demo.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'demo.dart';
|
||||
|
||||
const String _Text0 = """
|
||||
### **简介**
|
||||
> SimpleDialog 是一个用于向用户传递确定信息并提供选项的弹出层
|
||||
|
||||
|
||||
|
||||
### **基本用法**
|
||||
|
||||
> 通常作为子窗口小部件传递给showDialog,后者显示对话框。
|
||||
|
||||
""";
|
||||
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Dialog/SimpleDialog';
|
||||
|
||||
@override
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
title: 'SimpleDialog',
|
||||
codeUrl: 'components/Dialog/SimpleDialog/demo.dart',
|
||||
contentList: [
|
||||
_Text0,
|
||||
SimpleDialogDemo()
|
||||
],
|
||||
docUrl: 'https://docs.flutter.io/flutter/material/SimpleDialog-class.html',
|
||||
);
|
||||
}
|
||||
}
|
29
lib/widgets/components/Dialog/index.dart
Normal file
29
lib/widgets/components/Dialog/index.dart
Normal file
@ -0,0 +1,29 @@
|
||||
import "package:flutter/material.dart";
|
||||
import '../../../model/widget.dart';
|
||||
import 'AlertDialog/index.dart' as AlertDialog;
|
||||
import 'Dialog/index.dart' as Dialog;
|
||||
import 'SimpleDialog/index.dart' as SimpleDialog;
|
||||
import 'AboutDialog/index.dart' as AboutDialog;
|
||||
|
||||
List<WidgetPoint> widgetPoints = [
|
||||
WidgetPoint(
|
||||
name: 'AlertDialog',
|
||||
routerName: AlertDialog.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => AlertDialog.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name: 'Dialog',
|
||||
routerName: Dialog.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => Dialog.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name: 'SimpleDialog',
|
||||
routerName: SimpleDialog.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => SimpleDialog.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name: 'AboutDialog',
|
||||
routerName: AboutDialog.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => AboutDialog.Demo(),
|
||||
),
|
||||
];
|
60
lib/widgets/components/Grid/GridTile/demo.dart
Normal file
60
lib/widgets/components/Grid/GridTile/demo.dart
Normal file
@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 三帆
|
||||
* Date: 07/01/2019
|
||||
* Time: 10:31
|
||||
* email: sanfan.hx@alibaba-inc.com
|
||||
* tartget: xxx
|
||||
*/
|
||||
|
||||
import 'dart:math';
|
||||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
||||
class GridTileDemo extends StatefulWidget {
|
||||
_Demo createState() => _Demo();
|
||||
}
|
||||
|
||||
class _Demo extends State<GridTileDemo> {
|
||||
|
||||
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: 400,
|
||||
color: Color(0xffc91b3a),
|
||||
child: new GridView.count(
|
||||
crossAxisCount: 2,
|
||||
mainAxisSpacing: 10.0,
|
||||
crossAxisSpacing: 4.0,
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
childAspectRatio: 1.3,
|
||||
children: <Widget>[
|
||||
GridTile(
|
||||
header: Text("GridTile header", style: TextStyle(color: Colors.white)),
|
||||
child: Container(
|
||||
padding: EdgeInsets.fromLTRB(0, 30, 0, 0),
|
||||
child: Text("GridTile child", style: TextStyle(color: Colors.white)),
|
||||
),
|
||||
footer: Text("GridTile footer", style: TextStyle(color: Colors.white)),
|
||||
),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
],
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
47
lib/widgets/components/Grid/GridTile/index.dart
Normal file
47
lib/widgets/components/Grid/GridTile/index.dart
Normal file
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 三帆
|
||||
* Date: 07/01/2019
|
||||
* Time: 10:26
|
||||
* email: sanfan.hx@alibaba-inc.com
|
||||
* tartget: xxx
|
||||
*/
|
||||
import '../../../../common/widget_demo.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'demo.dart';
|
||||
|
||||
const String _Text0 = """
|
||||
### **简介**
|
||||
> GridTile 是GridList中的一种瓷片组件;包含header, body, footer三部份;
|
||||
|
||||
|
||||
### **基本用法**
|
||||
|
||||
> 一个grid列表包含多个Item, 每个Item通常包含一些视觉丰富的内容(例如,图像), 我们可以用GridTileBar去定义他的页眉与页脚。
|
||||
|
||||
如下实例中, 第一个是item便是GridTile组件构成. 包含header, body, footer;
|
||||
""";
|
||||
|
||||
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Grid/GridTile';
|
||||
|
||||
@override
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
title: 'GridTile',
|
||||
codeUrl: 'components/Grid/GridTile/demo.dart',
|
||||
contentList: [
|
||||
_Text0,
|
||||
GridTileDemo(),
|
||||
],
|
||||
docUrl: 'https://docs.flutter.io/flutter/material/Dialog-class.html',
|
||||
);
|
||||
}
|
||||
}
|
62
lib/widgets/components/Grid/GridTileBar/demo.dart
Normal file
62
lib/widgets/components/Grid/GridTileBar/demo.dart
Normal file
@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 三帆
|
||||
* Date: 07/01/2019
|
||||
* Time: 10:31
|
||||
* email: sanfan.hx@alibaba-inc.com
|
||||
* tartget: xxx
|
||||
*/
|
||||
|
||||
import 'dart:math';
|
||||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
||||
class GridTileDemo extends StatefulWidget {
|
||||
_Demo createState() => _Demo();
|
||||
}
|
||||
|
||||
class _Demo extends State<GridTileDemo> {
|
||||
|
||||
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: 400,
|
||||
color: Color(0xffc91b3a),
|
||||
child: new GridView.count(
|
||||
crossAxisCount: 2,
|
||||
mainAxisSpacing: 10.0,
|
||||
crossAxisSpacing: 4.0,
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
childAspectRatio: 1.3,
|
||||
children: <Widget>[
|
||||
GridTile(
|
||||
header: GridTileBar(
|
||||
title: Text('title'),
|
||||
subtitle: Text('subtitle'),
|
||||
leading: Icon(Icons.add),
|
||||
trailing: Text("trailing"),
|
||||
),
|
||||
child: Container(),
|
||||
|
||||
),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
],
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
51
lib/widgets/components/Grid/GridTileBar/index.dart
Normal file
51
lib/widgets/components/Grid/GridTileBar/index.dart
Normal file
@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 三帆
|
||||
* Date: 07/01/2019
|
||||
* Time: 10:26
|
||||
* email: sanfan.hx@alibaba-inc.com
|
||||
* tartget: xxx
|
||||
*/
|
||||
import '../../../../common/widget_demo.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'demo.dart';
|
||||
|
||||
const String _Text0 = """
|
||||
### **简介**
|
||||
> GridTileBar 通常用来做GridTile的header与footer组件;
|
||||
|
||||
|
||||
### **基本用法**
|
||||
|
||||
> GridTileBar含有五个属性
|
||||
|
||||
- backgroundColor 描述GridTileBar的背景颜色
|
||||
- leading GridTileBar左侧的widget, 通常我们用图标来占位
|
||||
- subtitle 次标题
|
||||
- title 主标题
|
||||
- trailing GridTileBar右侧的widgett, 通常我们用来做交互操作类的组件
|
||||
""";
|
||||
|
||||
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Grid/GridTileBar';
|
||||
|
||||
@override
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
title: 'GridTileBar',
|
||||
codeUrl: 'components/Grid/GridTileBar/demo.dart',
|
||||
contentList: [
|
||||
_Text0,
|
||||
GridTileDemo(),
|
||||
],
|
||||
docUrl: 'https://docs.flutter.io/flutter/material/GridTileBar-class.html',
|
||||
);
|
||||
}
|
||||
}
|
62
lib/widgets/components/Grid/GridView/demo.dart
Normal file
62
lib/widgets/components/Grid/GridView/demo.dart
Normal file
@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 三帆
|
||||
* Date: 07/01/2019
|
||||
* Time: 10:31
|
||||
* email: sanfan.hx@alibaba-inc.com
|
||||
* tartget: xxx
|
||||
*/
|
||||
|
||||
import 'dart:math';
|
||||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
||||
class GridTileDemo extends StatefulWidget {
|
||||
_Demo createState() => _Demo();
|
||||
}
|
||||
|
||||
class _Demo extends State<GridTileDemo> {
|
||||
|
||||
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: 400,
|
||||
color: Color(0xffc91b3a),
|
||||
child: new GridView.count(
|
||||
crossAxisCount: 2,
|
||||
mainAxisSpacing: 10.0,
|
||||
crossAxisSpacing: 4.0,
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
childAspectRatio: 1.3,
|
||||
children: <Widget>[
|
||||
GridTile(
|
||||
header: GridTileBar(
|
||||
title: Text('title'),
|
||||
subtitle: Text('subtitle'),
|
||||
leading: Icon(Icons.add),
|
||||
trailing: Text("trailing"),
|
||||
),
|
||||
child: Container(),
|
||||
|
||||
),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
new Image.network('https://flutter.io/assets/homepage/news-2-599aefd56e8aa903ded69500ef4102cdd8f988dab8d9e4d570de18bdb702ffd4.png', scale: 1, fit: BoxFit.cover),
|
||||
],
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
45
lib/widgets/components/Grid/GridView/index.dart
Normal file
45
lib/widgets/components/Grid/GridView/index.dart
Normal file
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 三帆
|
||||
* Date: 07/01/2019
|
||||
* Time: 10:26
|
||||
* email: sanfan.hx@alibaba-inc.com
|
||||
* tartget: xxx
|
||||
*/
|
||||
import '../../../../common/widget_demo.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'demo.dart';
|
||||
|
||||
const String _Text0 = """
|
||||
### **简介**
|
||||
> GridView 通常用来做GridTile的header与footer组件;
|
||||
|
||||
|
||||
### **基本用法**
|
||||
|
||||
> 1231
|
||||
""";
|
||||
|
||||
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Grid/GridView';
|
||||
|
||||
@override
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
title: 'GridTileBar',
|
||||
codeUrl: 'components/Grid/GridView/demo.dart',
|
||||
contentList: [
|
||||
_Text0,
|
||||
GridTileDemo(),
|
||||
],
|
||||
docUrl: 'https://docs.flutter.io/flutter/material/GridView-class.html',
|
||||
);
|
||||
}
|
||||
}
|
26
lib/widgets/components/Grid/index.dart
Normal file
26
lib/widgets/components/Grid/index.dart
Normal file
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 三帆
|
||||
* Date: 07/01/2019
|
||||
* Time: 19:40
|
||||
* email: sanfan.hx@alibaba-inc.com
|
||||
* tartget: xxx
|
||||
*/
|
||||
|
||||
import "package:flutter/material.dart";
|
||||
import '../../../model/widget.dart';
|
||||
import 'GridTile/index.dart' as GridTile;
|
||||
|
||||
import 'GridTileBar/index.dart' as GridTileBar;
|
||||
List<WidgetPoint> widgetPoints = [
|
||||
WidgetPoint(
|
||||
name: 'GridTile',
|
||||
routerName: GridTile.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => GridTile.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name: 'GridTileBar',
|
||||
routerName: GridTileBar.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => GridTileBar.Demo(),
|
||||
)
|
||||
];
|
131
lib/widgets/components/LIst/AnimatedList/demo.dart
Normal file
131
lib/widgets/components/LIst/AnimatedList/demo.dart
Normal file
@ -0,0 +1,131 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import './model.dart';
|
||||
|
||||
class AnimatedListFullDefault extends StatefulWidget {
|
||||
AnimatedListFullDefault({Key key, this.parent}) : super(key: key);
|
||||
final parent;
|
||||
|
||||
@override
|
||||
_AnimatedListFullDefault createState() => _AnimatedListFullDefault();
|
||||
}
|
||||
|
||||
/*
|
||||
* AnimatedList 默认的实例,有状态
|
||||
* */
|
||||
class _AnimatedListFullDefault extends State<AnimatedListFullDefault> {
|
||||
final GlobalKey<AnimatedListState> _listKey = new GlobalKey<AnimatedListState>();
|
||||
ListModel<int> _list;
|
||||
int _selectedItem;
|
||||
int _nextItem; // The next item inserted when the user presses the '+' button.
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (widget.parent is State) {
|
||||
widget.parent.animatedList = this; // 修改父级的对象引用
|
||||
}
|
||||
_list = new ListModel<int>(
|
||||
listKey: _listKey,
|
||||
initialItems: <int>[0, 1, 2],
|
||||
removedItemBuilder: _buildRemovedItem,
|
||||
);
|
||||
_nextItem = 3;
|
||||
}
|
||||
|
||||
void insert() {
|
||||
final int index = _selectedItem == null ? _list.length : _list.indexOf(_selectedItem);
|
||||
_list.insert(index, _nextItem++);
|
||||
}
|
||||
|
||||
// Remove the selected item from the list model.
|
||||
void remove() {
|
||||
if (_selectedItem != null) {
|
||||
_list.removeAt(_list.indexOf(_selectedItem));
|
||||
setState(() {
|
||||
_selectedItem = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildItem(BuildContext context, int index, Animation<double> animation) {
|
||||
return new CardItem(
|
||||
animation: animation,
|
||||
item: _list[index],
|
||||
selected: _selectedItem == _list[index],
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_selectedItem = _selectedItem == _list[index] ? null : _list[index];
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildRemovedItem(int item, BuildContext context, Animation<double> animation) {
|
||||
return new CardItem(
|
||||
animation: animation,
|
||||
item: item,
|
||||
selected: false,
|
||||
// No gesture detector here: we don't want removed items to be interactive.
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
height: 500.0,
|
||||
child:AnimatedList(
|
||||
//shrinkWrap: true,
|
||||
key: _listKey,
|
||||
initialItemCount: _list.length,
|
||||
itemBuilder: _buildItem,
|
||||
));
|
||||
}
|
||||
void methodA() {}
|
||||
}
|
||||
|
||||
class CardItem extends StatelessWidget {
|
||||
const CardItem({
|
||||
Key key,
|
||||
@required this.animation,
|
||||
this.onTap,
|
||||
@required this.item,
|
||||
this.selected: false
|
||||
}) : assert(animation != null),
|
||||
assert(item != null && item >= 0),
|
||||
assert(selected != null),
|
||||
super(key: key);
|
||||
|
||||
final Animation<double> animation;
|
||||
final VoidCallback onTap;
|
||||
final int item;
|
||||
final bool selected;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
TextStyle textStyle = Theme.of(context).textTheme.display1;
|
||||
if (selected)
|
||||
textStyle = textStyle.copyWith(color: Colors.lightGreenAccent[400]);
|
||||
return new Padding(
|
||||
padding: const EdgeInsets.all(2.0),
|
||||
child: new SizeTransition(
|
||||
axis: Axis.vertical,
|
||||
sizeFactor: animation,
|
||||
child: new GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: onTap,
|
||||
child: new SizedBox(
|
||||
height: 128.0,
|
||||
child: new Card(
|
||||
color: Colors.primaries[item % Colors.primaries.length],
|
||||
child: new Center(
|
||||
child: new Text('Item $item', style: textStyle),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
116
lib/widgets/components/LIst/AnimatedList/index.dart
Normal file
116
lib/widgets/components/LIst/AnimatedList/index.dart
Normal file
@ -0,0 +1,116 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2018/12/31
|
||||
* Time: 下午9:48
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: AnimatedList 的示例
|
||||
*/
|
||||
import '../../../../common/widget-demo.dart';
|
||||
import '../../../../routers/application.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import './demo.dart';
|
||||
|
||||
|
||||
//var _AnimatedListFullDefault = AnimatedListDemo.AnimatedListFullDefault;
|
||||
GlobalKey globalKey = GlobalKey();
|
||||
|
||||
const String _Text0 =
|
||||
"""### **简介**
|
||||
> AnimatedList “动画滚动容器”
|
||||
- 一个滚动容器,可在插入或移除项目时为其设置动画
|
||||
""";
|
||||
|
||||
|
||||
const String _Text1 =
|
||||
"""### **基本用法**
|
||||
> AnimatedList
|
||||
- AnimatedListState 可用于动态插入或删除项目。
|
||||
- 下面示例展示效果:点击+号增加 card, 点击 card 保持激活状态,再点击-号,减少 card。
|
||||
""";
|
||||
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components//List/AnimatedList';
|
||||
|
||||
@override
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
var animatedList = null;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
title: 'AnimatedList',
|
||||
codeUrl: '${Application.github['widgetsURL']}componentss/List/AnimatedList/demo.dart',
|
||||
child: allCheckboxs(context, this),
|
||||
docUrl: 'https://docs.flutter.io/flutter/widgets/AnimatedList-class.html',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 所有的 AnimatedList widget
|
||||
* context: 运行上下文
|
||||
* that: 指向有状态的 StatefulWidget
|
||||
*/
|
||||
Widget allCheckboxs(BuildContext context, _DemoState that) {
|
||||
return Container(
|
||||
//padding: new EdgeInsets.only(bottom: 20.0, top: 20.0, left: 0, right: 0),
|
||||
child: Column(
|
||||
//mainAxisSize: MainAxisSize.max,
|
||||
children: <Widget>[
|
||||
MarkdownBody(data: _Text0),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
MarkdownBody(data: _Text1),
|
||||
ButtonBar(
|
||||
alignment: MainAxisAlignment.spaceAround,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: <Widget>[
|
||||
assistButtonLeft(that),
|
||||
SizedBox(width: 20.0), // 间距
|
||||
assistButtonRight(that),
|
||||
],
|
||||
),
|
||||
//AnimatedListDemo.AnimatedListFullDefault(key:globalKey,parent:context),
|
||||
AnimatedListFullDefault(key:globalKey,parent:that),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* 演示辅助按钮
|
||||
* */
|
||||
Widget assistButtonLeft(that) {
|
||||
return FloatingActionButton(
|
||||
// 文本内容
|
||||
backgroundColor:Colors.red,
|
||||
child: const Icon(Icons.add_circle_outline),
|
||||
heroTag: null, // 不加这个参数会黑屏...
|
||||
onPressed: () {
|
||||
//demo.insert();
|
||||
//print('${globalKey.currentState}');
|
||||
that.animatedList.insert();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* 演示辅助按钮
|
||||
* */
|
||||
Widget assistButtonRight(that) {
|
||||
return FloatingActionButton(
|
||||
// 文本内容
|
||||
backgroundColor:Colors.green,
|
||||
child: const Icon(Icons.remove_circle_outline),
|
||||
heroTag: null, // 不加这个参数会黑屏...
|
||||
onPressed: () {
|
||||
that.animatedList.remove();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
54
lib/widgets/components/LIst/AnimatedList/model.dart
Normal file
54
lib/widgets/components/LIst/AnimatedList/model.dart
Normal file
@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 一晟
|
||||
* Date: 2018/12/31
|
||||
* Time: 下午10:15
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: FlatButton 的示例
|
||||
*/
|
||||
/// Keeps a Dart List in sync with an AnimatedList.
|
||||
///
|
||||
/// The [insert] and [removeAt] methods apply to both the internal list and the
|
||||
/// animated list that belongs to [listKey].
|
||||
///
|
||||
/// This class only exposes as much of the Dart List API as is needed by the
|
||||
/// sample app. More list methods are easily added, however methods that mutate the
|
||||
/// list must make the same changes to the animated list in terms of
|
||||
/// [AnimatedListState.insertItem] and [AnimatedList.removeItem].
|
||||
///
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ListModel<E> {
|
||||
ListModel({
|
||||
@required this.listKey,
|
||||
@required this.removedItemBuilder,
|
||||
Iterable<E> initialItems,
|
||||
}) : assert(listKey != null),
|
||||
assert(removedItemBuilder != null),
|
||||
_items = new List<E>.from(initialItems ?? <E>[]);
|
||||
|
||||
final GlobalKey<AnimatedListState> listKey;
|
||||
final dynamic removedItemBuilder;
|
||||
final List<E> _items;
|
||||
|
||||
AnimatedListState get _animatedList => listKey.currentState;
|
||||
|
||||
void insert(int index, E item) {
|
||||
_items.insert(index, item);
|
||||
_animatedList.insertItem(index);
|
||||
}
|
||||
|
||||
E removeAt(int index) {
|
||||
final E removedItem = _items.removeAt(index);
|
||||
if (removedItem != null) {
|
||||
_animatedList.removeItem(index, (BuildContext context, Animation<double> animation) {
|
||||
return removedItemBuilder(removedItem, context, animation);
|
||||
});
|
||||
}
|
||||
return removedItem;
|
||||
}
|
||||
|
||||
int get length => _items.length;
|
||||
E operator [](int index) => _items[index];
|
||||
int indexOf(E item) => _items.indexOf(item);
|
||||
}
|
75
lib/widgets/components/LIst/ListBody/demo.dart
Normal file
75
lib/widgets/components/LIst/ListBody/demo.dart
Normal file
@ -0,0 +1,75 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2018/12/31
|
||||
* Time: 下午2:42
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: ListBody 的示例
|
||||
*/
|
||||
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/*
|
||||
* Checkbox 默认按钮的实例
|
||||
* index 当前checkbox 的索引值
|
||||
* */
|
||||
class ListBodyFullDefault extends StatefulWidget {
|
||||
const ListBodyFullDefault() : super();
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _ListBodyFullDefault();
|
||||
}
|
||||
|
||||
/*
|
||||
* ListBody 默认的实例,有状态
|
||||
* */
|
||||
class _ListBodyFullDefault extends State {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListBody(
|
||||
// ... // 如果没有,就是不需要有状态的 StatefulWidget
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ListBody 默认的实例,无状态
|
||||
* */
|
||||
class ListBodyLessDefault extends StatelessWidget {
|
||||
final widget;
|
||||
final parent;
|
||||
|
||||
const ListBodyLessDefault([this.widget, this.parent])
|
||||
: super();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListBody(
|
||||
mainAxis: Axis.vertical, // 排列的主轴方向
|
||||
reverse: false, // 是否反向
|
||||
children: <Widget>[
|
||||
Container(color: Colors.red,
|
||||
width: 50.0,
|
||||
height: 150.0,
|
||||
child: Text('标题1', style: TextStyle(color: Color(0xffffffff)))),
|
||||
Container(color: Colors.yellow,
|
||||
width: 50.0,
|
||||
height: 50.0,
|
||||
child: Text('标题2', style: TextStyle(color: Color(0xffffffff)))),
|
||||
Container(color: Colors.green,
|
||||
width: 50.0,
|
||||
height: 50.0,
|
||||
child: Text('标题3', style: TextStyle(color: Color(0xffffffff)))),
|
||||
Container(color: Colors.blue,
|
||||
width: 50.0,
|
||||
height: 50.0,
|
||||
child: Text('标题4', style: TextStyle(color: Color(0xffffffff)))),
|
||||
Container(color: Colors.black,
|
||||
width: 50.0,
|
||||
height: 50.0,
|
||||
child: Text('标题5', style: TextStyle(color: Color(0xffffffff))))
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
72
lib/widgets/components/LIst/ListBody/index.dart
Normal file
72
lib/widgets/components/LIst/ListBody/index.dart
Normal file
@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2018/12/31
|
||||
* Time: 下午2:38
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: ListBody 的示例
|
||||
*/
|
||||
import '../../../../common/widget-demo.dart';
|
||||
import '../../../../routers/application.dart';
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import './demo.dart' as ListBodyDemo;
|
||||
|
||||
const String _Text0 =
|
||||
"""### **简介**
|
||||
> ListBody “列表组件”
|
||||
- 作用是按给定的轴方向,按照顺序排列子节点。
|
||||
- 是一个不常直接使用的控件,一般都会配合ListView或者Column等控件使用。
|
||||
""";
|
||||
|
||||
|
||||
const String _Text1 =
|
||||
"""### **基本用法**
|
||||
> 布局行为
|
||||
- 在主轴上,子节点按照顺序进行布局,在交叉轴上,子节点尺寸会被拉伸,以适应交叉轴的区域。
|
||||
- 在主轴上,给予子节点的空间必须是不受限制的(unlimited),使得子节点可以全部被容纳,ListBody不会去裁剪或者缩放其子节点。
|
||||
- ListBody的布局代码非常简单,根据主轴的方向,对子节点依次排布。
|
||||
""";
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components//List/ListBody';
|
||||
|
||||
@override
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
title: 'ListBody',
|
||||
codeUrl: '${Application
|
||||
.github['widgetsURL']}/componentss/List/ListBody/demo.dart',
|
||||
child: allCheckboxs(context, this),
|
||||
docUrl: 'https://docs.flutter.io/flutter/widgets/ListBody-class.html',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 所有的 ListBody widget
|
||||
* context: 运行上下文
|
||||
* that: 指向有状态的 StatefulWidget
|
||||
*/
|
||||
Widget allCheckboxs(BuildContext context, _DemoState that) {
|
||||
return Container(
|
||||
//padding: new EdgeInsets.only(bottom: 20.0, top: 20.0, left: 0, right: 0),
|
||||
child: Column(
|
||||
//mainAxisSize: MainAxisSize.max,
|
||||
children: <Widget>[
|
||||
MarkdownBody(data: _Text0),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
MarkdownBody(data: _Text1),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
ListBodyDemo.ListBodyLessDefault(),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
])
|
||||
);
|
||||
}
|
142
lib/widgets/components/LIst/ListView/demo.dart
Normal file
142
lib/widgets/components/LIst/ListView/demo.dart
Normal file
@ -0,0 +1,142 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2018/12/31
|
||||
* Time: 下午2:27
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: ListView 的示例
|
||||
*/
|
||||
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/*
|
||||
* Checkbox 默认按钮的实例
|
||||
* index 当前checkbox 的索引值
|
||||
* */
|
||||
class ListViewFullDefault extends StatefulWidget {
|
||||
const ListViewFullDefault() : super();
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _ListViewFullDefault();
|
||||
}
|
||||
|
||||
/*
|
||||
* ListView 默认的实例,有状态
|
||||
* */
|
||||
class _ListViewFullDefault extends State {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListView(
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ListView 默认的实例,无状态
|
||||
* */
|
||||
class ListViewLessDefault extends StatelessWidget {
|
||||
final widget;
|
||||
final parent;
|
||||
final index;
|
||||
|
||||
const ListViewLessDefault([this.index, this.widget, this.parent,])
|
||||
: super();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
switch(index){
|
||||
case 0:
|
||||
return ListView(
|
||||
shrinkWrap: true,
|
||||
padding: EdgeInsets.all(20.0),
|
||||
children: <Widget>[
|
||||
Text('I\'m dedicating every day to you'),
|
||||
ListTile(
|
||||
leading: Icon(Icons.map),
|
||||
title: Text('Maps'),
|
||||
),
|
||||
Text('Domestic life was never quite my style'),
|
||||
ListTile(
|
||||
leading: Icon(Icons.photo_album),
|
||||
title: Text('Album'),
|
||||
),
|
||||
Text('When you smile, you knock me out, I fall apart'),
|
||||
ListTile(
|
||||
leading: Icon(Icons.phone),
|
||||
title: Text('Phone'),
|
||||
),
|
||||
Text('And I thought I was so smart'),
|
||||
],
|
||||
);
|
||||
break;
|
||||
case 1:
|
||||
return SizedBox(
|
||||
height: 300.0,
|
||||
child: ListView.builder(
|
||||
scrollDirection: Axis.vertical,
|
||||
itemCount: 10, // item 的个数
|
||||
itemExtent: 50.0, // 如果为非null,则强制子项在滚动方向上具有给定范围
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return ListTile(
|
||||
title: Text("title $index"), // item 标题
|
||||
leading: Icon(Icons.keyboard), // item 前置图标
|
||||
subtitle: Text("subtitle $index"), // item 副标题
|
||||
trailing: Icon(Icons.keyboard_arrow_right),// item 后置图标
|
||||
isThreeLine:false, // item 是否三行显示
|
||||
dense:true, // item 直观感受是整体大小
|
||||
contentPadding: EdgeInsets.all(10.0),// item 内容内边距
|
||||
enabled:true,
|
||||
onTap:(){print('点击:${index}');},// item onTap 点击事件
|
||||
onLongPress:(){print('长按:${index}');},// item onLongPress 长按事件
|
||||
selected:false, // item 是否选中状态
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
break;
|
||||
case 2:
|
||||
return SizedBox(
|
||||
height: 300.0,
|
||||
child: ListView.separated(
|
||||
scrollDirection: Axis.vertical,
|
||||
itemCount: 100, // item 的个数
|
||||
separatorBuilder: (BuildContext context, int index) => Divider(height:1.0,color: Colors.blue), // 添加分割线
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return ListTile(
|
||||
title: Text("title $index"), // item 标题
|
||||
leading: Icon(Icons.keyboard), // item 前置图标
|
||||
subtitle: Text("subtitle $index"), // item 副标题
|
||||
trailing: Icon(Icons.keyboard_arrow_right),// item 后置图标
|
||||
isThreeLine:false, // item 是否三行显示
|
||||
dense:true, // item 直观感受是整体大小
|
||||
contentPadding: EdgeInsets.all(10.0),// item 内容内边距
|
||||
enabled:true,
|
||||
onTap:(){print('点击:${index}');},// item onTap 点击事件
|
||||
onLongPress:(){print('长按:${index}');},// item onLongPress 长按事件
|
||||
selected:false, // item 是否选中状态
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
break;
|
||||
case 3:
|
||||
return SizedBox(
|
||||
height: 300.0,
|
||||
child: ListView.custom(
|
||||
scrollDirection: Axis.vertical,
|
||||
childrenDelegate:SliverChildBuilderDelegate((BuildContext context, int index) {
|
||||
return Container(
|
||||
height: 50.0,
|
||||
alignment: Alignment.center,
|
||||
color: Colors.lightBlue[100 * (index % 9)],
|
||||
child: Text('list item $index'),
|
||||
);
|
||||
}, childCount: 10),
|
||||
),
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
122
lib/widgets/components/LIst/ListView/index.dart
Normal file
122
lib/widgets/components/LIst/ListView/index.dart
Normal file
@ -0,0 +1,122 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2018/12/31
|
||||
* Time: 下午2:25
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: ListView 的示例
|
||||
*/
|
||||
import '../../../../common/widget-demo.dart';
|
||||
import '../../../../routers/application.dart';
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import './demo.dart' as ListViewDemo;
|
||||
|
||||
const String _Text0 =
|
||||
"""### **简介**
|
||||
> ListView “滚动列表”
|
||||
- 一个非常常用的控件,涉及到数据列表展示的,一般情况下都会选用该控件。
|
||||
- 跟GridView相似,基本上是一个slivers里面只包含一个SliverList的CustomScrollView。
|
||||
""";
|
||||
|
||||
|
||||
const String _Text1 =
|
||||
"""### **基本用法**
|
||||
> 布局行为
|
||||
|
||||
- ListView在主轴方向可以滚动,在交叉轴方向,则是填满ListView。
|
||||
- 一个组合控件。ListView跟GridView类似,都是继承自BoxScrollView。
|
||||
- ### 在Flutter中有几种构建ListView的方式,分别是: **默认List,ListView.builder, ListView.separated,ListView.custom**。
|
||||
""";
|
||||
|
||||
const String _Text2 =
|
||||
"""
|
||||
> ListView()
|
||||
- 默认 List 方式,是把数据 Iterable 添加到列表中,之后直接添加到 ListView 即可。
|
||||
- Tips: 如果需要设置分割线,需要对列表 item 添加处理,ListTile.divideTiles。
|
||||
- 仅适用于内容较少的情形,因为它是一次性渲染所有的 items ,当 items 的数目较多时,很容易出现卡顿现象的,导致滑动不流畅。
|
||||
""";
|
||||
|
||||
const String _Text3 =
|
||||
"""
|
||||
> ListView.builder()
|
||||
- 设置单个item的属性,懒加载的,假如有 1000 个列表,初始渲染时并不会所有都渲染,而只会特定数量的 item ,这对于性能和用户体验来说,是很好的提升。
|
||||
""";
|
||||
|
||||
const String _Text4 =
|
||||
"""
|
||||
> 官方示例 ListView.separated()
|
||||
- 带分割线的item,separated 相比较于 builder,又多了一个参数 separatorBuilder ,用于控制列表各个元素的间隔如何渲染。
|
||||
""";
|
||||
|
||||
const String _Text5 =
|
||||
"""
|
||||
> 官方示例 ListView.custom()
|
||||
- 必须的参数就是 childrenDelegate , 然后传入一个 实现了 SliverChildDelegate 的组件,如 SliverChildListDelegate 和 SliverChildBuilderDelegate。
|
||||
""";
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/List/ListView';
|
||||
|
||||
@override
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
title: 'ListView',
|
||||
codeUrl: '${Application.github['widgetsURL']}/componentss/List/ListView/demo.dart',
|
||||
child: allCheckboxs(context, this),
|
||||
docUrl: 'https://docs.flutter.io/flutter/widgets/ListView-class.html',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 所有的 ListView widget
|
||||
* context: 运行上下文
|
||||
* that: 指向有状态的 StatefulWidget
|
||||
*/
|
||||
Widget allCheckboxs(BuildContext context, _DemoState that) {
|
||||
return Container(
|
||||
//padding: new EdgeInsets.only(bottom: 20.0, top: 20.0, left: 0, right: 0),
|
||||
child: Column(
|
||||
//mainAxisSize: MainAxisSize.max,
|
||||
children: <Widget>[
|
||||
MarkdownBody(data: _Text0),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
MarkdownBody(data: _Text1),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
MarkdownBody(data: _Text2),
|
||||
ListViewDemo.ListViewLessDefault(0),
|
||||
MarkdownBody(data: _Text3),
|
||||
ListViewDemo.ListViewLessDefault(1),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
MarkdownBody(data: _Text4),
|
||||
ListViewDemo.ListViewLessDefault(2),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
MarkdownBody(data: _Text5),
|
||||
ListViewDemo.ListViewLessDefault(3),
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* 带align的text
|
||||
* */
|
||||
Widget textAlignBar(String txt) {
|
||||
return new Align(
|
||||
alignment: FractionalOffset.centerLeft,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
SizedBox(height: 20.0),
|
||||
MarkdownBody(data: txt)
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
|
32
lib/widgets/components/LIst/index.dart
Normal file
32
lib/widgets/components/LIst/index.dart
Normal file
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 一晟
|
||||
* Date: 2018/12/27
|
||||
* Time: 下午2:50
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: FlatButton 的示例
|
||||
*/
|
||||
import "package:flutter/material.dart";
|
||||
import '../../../model/widget.dart';
|
||||
|
||||
import 'ListBody/index.dart' as ListBody;
|
||||
import 'ListView/index.dart' as ListView;
|
||||
import 'AnimatedList/index.dart' as AnimatedList;
|
||||
|
||||
List<WidgetPoint> widgetPoints = [
|
||||
WidgetPoint(
|
||||
name: 'ListBody',
|
||||
routerName: ListBody.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => ListBody.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name: 'ListView',
|
||||
routerName: ListView.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => ListView.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name: 'AnimatedList',
|
||||
routerName: AnimatedList.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => AnimatedList.Demo(),
|
||||
)
|
||||
];
|
90
lib/widgets/components/Menu/CheckedPopupMenuItem/demo.dart
Normal file
90
lib/widgets/components/Menu/CheckedPopupMenuItem/demo.dart
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* @Author: 一凨
|
||||
* @Date: 2018-12-22 21:01:51
|
||||
* @Last Modified by: 一凨
|
||||
* @Last Modified time: 2018-12-27 15:37:04
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
|
||||
class CheckedPopupMenuItemDemo extends StatefulWidget {
|
||||
_CheckedPopupMenuItemDemoState createState() =>
|
||||
_CheckedPopupMenuItemDemoState();
|
||||
}
|
||||
|
||||
class _CheckedPopupMenuItemDemoState extends State<CheckedPopupMenuItemDemo> {
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
List<String> _checkedValues;
|
||||
|
||||
final String _checkedValue1 = 'One';
|
||||
final String _checkedValue2 = 'Two';
|
||||
final String _checkedValue3 = 'Free';
|
||||
final String _checkedValue4 = 'Four';
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_checkedValues = <String>[_checkedValue3];
|
||||
}
|
||||
|
||||
void showInSnackBar(String value){
|
||||
Fluttertoast.showToast(
|
||||
msg: value,
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.CENTER,
|
||||
timeInSecForIos: 1,
|
||||
backgroundColor: Colors.grey,
|
||||
textColor: Colors.white
|
||||
);
|
||||
}
|
||||
|
||||
bool isChecked(String value) => _checkedValues.contains(value);
|
||||
|
||||
|
||||
void showCheckedMenuSelections(String value){
|
||||
if(_checkedValues.contains(value)){
|
||||
_checkedValues.remove(value);
|
||||
}else{
|
||||
_checkedValues.add(value);
|
||||
}
|
||||
showInSnackBar('Checked $_checkedValues');
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
color: Theme.of(context).primaryColor,
|
||||
child: ListTile(
|
||||
title: const Text('CheckedPopupMenuItem Demo',style: TextStyle(color: Colors.white),),
|
||||
trailing: PopupMenuButton<String>(
|
||||
padding: EdgeInsets.zero,
|
||||
onSelected: showCheckedMenuSelections,
|
||||
icon: Icon(Icons.menu,color: Colors.white,),
|
||||
itemBuilder: (BuildContext context)=><PopupMenuItem<String>>[
|
||||
CheckedPopupMenuItem<String>(
|
||||
value: _checkedValue1,
|
||||
checked: isChecked(_checkedValue1),
|
||||
child: Text(_checkedValue1)
|
||||
),
|
||||
CheckedPopupMenuItem<String>(
|
||||
value: _checkedValue2,
|
||||
enabled: false,
|
||||
checked: isChecked(_checkedValue2),
|
||||
child: Text(_checkedValue2)
|
||||
),
|
||||
CheckedPopupMenuItem<String>(
|
||||
value: _checkedValue3,
|
||||
checked: isChecked(_checkedValue3),
|
||||
child: Text(_checkedValue3)
|
||||
),
|
||||
CheckedPopupMenuItem<String>(
|
||||
value: _checkedValue4,
|
||||
checked: isChecked(_checkedValue4),
|
||||
child: Text(_checkedValue4)
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
44
lib/widgets/components/Menu/CheckedPopupMenuItem/index.dart
Normal file
44
lib/widgets/components/Menu/CheckedPopupMenuItem/index.dart
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* @Author: 一凨
|
||||
* @Date: 2018-12-22 21:01:45
|
||||
* @Last Modified by: 一凨
|
||||
* @Last Modified time: 2018-12-22 21:26:54
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../common/widget_demo.dart';
|
||||
import './demo.dart';
|
||||
|
||||
const String content0 = '''
|
||||
### **简介**
|
||||
> 带有选中标记的 Material 设计风格的弹出菜单
|
||||
- 默认高度为48px,水平布局使用 ListTile 复选标记是 Icons.done 图标,显示在 leading 位置
|
||||
- 只有在状态为选中时才会显示图标
|
||||
''';
|
||||
|
||||
const String content1 = '''
|
||||
### **基本用法**
|
||||
> 配合 PopupMenuButton 使用
|
||||
- enabled 属性控制item是否为可点击
|
||||
- checked 标识item是否为选中状态
|
||||
''';
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Menu/CheckedPopupMenuItem';
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
codeUrl: 'components/Menu/CheckedPopupMenuItem/demo.dart',
|
||||
docUrl: 'https://docs.flutter.io/flutter/material/CheckedPopupMenuItem-class.html',
|
||||
title: 'CheckedPopupMenuItem',
|
||||
contentList: [
|
||||
content0,
|
||||
content1,
|
||||
CheckedPopupMenuItemDemo(),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
95
lib/widgets/components/Menu/DropdownMenuItem/demo.dart
Normal file
95
lib/widgets/components/Menu/DropdownMenuItem/demo.dart
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* @Author: 一凨
|
||||
* @Date: 2018-12-27 14:05:32
|
||||
* @Last Modified by: 一凨
|
||||
* @Last Modified time: 2018-12-27 14:05:52
|
||||
*/
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class DropdownMenuItemDemo extends StatefulWidget {
|
||||
_DropdownMenuItemDemoState createState() => _DropdownMenuItemDemoState();
|
||||
}
|
||||
|
||||
class _DropdownMenuItemDemoState extends State<DropdownMenuItemDemo> {
|
||||
|
||||
String dropdown1Value = 'Free';
|
||||
String dropdown2Value;
|
||||
String dropdown3Value = 'Four';
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(24.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
ListTile(
|
||||
title: const Text('Simple dropdown:'),
|
||||
trailing: DropdownButton<String>(
|
||||
value: dropdown1Value,
|
||||
onChanged: (String newValue) {
|
||||
setState(() {
|
||||
dropdown1Value = newValue;
|
||||
});
|
||||
},
|
||||
items: <String>['One', 'Two', 'Free', 'Four'].map<DropdownMenuItem<String>>((String value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value,
|
||||
child: Text(value),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 24.0,
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('Dropdown with a hint:'),
|
||||
trailing: DropdownButton<String>(
|
||||
value: dropdown2Value,
|
||||
hint: const Text('Choose'),
|
||||
onChanged: (String newValue) {
|
||||
setState(() {
|
||||
dropdown2Value = newValue;
|
||||
});
|
||||
},
|
||||
items: <String>['One', 'Two', 'Free', 'Four'].map<DropdownMenuItem<String>>((String value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value,
|
||||
child: Text(value),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 24.0,
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('Scrollable dropdown:'),
|
||||
trailing: DropdownButton<String>(
|
||||
value: dropdown3Value,
|
||||
onChanged: (String newValue) {
|
||||
setState(() {
|
||||
dropdown3Value = newValue;
|
||||
});
|
||||
},
|
||||
items: <String>[
|
||||
'One', 'Two', 'Free', 'Four', 'Can', 'I', 'Have', 'A', 'Little',
|
||||
'Bit', 'More', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten'
|
||||
]
|
||||
.map<DropdownMenuItem<String>>((String value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value,
|
||||
child: Text(value),
|
||||
);
|
||||
})
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
46
lib/widgets/components/Menu/DropdownMenuItem/index.dart
Normal file
46
lib/widgets/components/Menu/DropdownMenuItem/index.dart
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* @Author: 一凨
|
||||
* @Date: 2018-12-27 11:20:07
|
||||
* @Last Modified by: 一凨
|
||||
* @Last Modified time: 2018-12-27 14:51:44
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../common/widget_demo.dart';
|
||||
import './demo.dart';
|
||||
|
||||
|
||||
const String content0 = '''
|
||||
### **简介**
|
||||
> DropdownButton 创建的一个菜单项
|
||||
- DropdownButton 是 Material 设计风格中的一个从列表中选择某一个item的按钮
|
||||
- DropdownButton 按钮显示选定的Item的值以及打开用于选择其他item的菜单箭头
|
||||
- DropdownMenuItem<T> 这里面的T代表入参的类型,注意在给定菜单中,所有的item的类型要保持一致
|
||||
''';
|
||||
|
||||
const String content1 = '''
|
||||
### **基本用法**
|
||||
> 配合 DropdownButton 使用
|
||||
- value 选中返回的值
|
||||
- child 子Widget项
|
||||
''';
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Menu/DropdownMenuItem';
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
contentList: [
|
||||
content0,
|
||||
content1,
|
||||
DropdownMenuItemDemo(),
|
||||
],
|
||||
title: 'DropdownMenuItem',
|
||||
docUrl: 'https://docs.flutter.io/flutter/material/DropdownMenuItem-class.html',
|
||||
codeUrl: 'components/Menu/DropdownMenuItem/demo.dart',
|
||||
);
|
||||
}
|
||||
}
|
153
lib/widgets/components/Menu/PopupMenuButton/demo.dart
Normal file
153
lib/widgets/components/Menu/PopupMenuButton/demo.dart
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* @Author: 一凨
|
||||
* @Date: 2018-12-27 15:17:10
|
||||
* @Last Modified by: 一凨
|
||||
* @Last Modified time: 2018-12-27 15:39:35
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
|
||||
class PopupMenuButtonDemo extends StatefulWidget {
|
||||
_PopupMenuButtonDemoState createState() => _PopupMenuButtonDemoState();
|
||||
}
|
||||
|
||||
class _PopupMenuButtonDemoState extends State<PopupMenuButtonDemo> {
|
||||
final String _simpleValue1 = 'Menu item value one';
|
||||
final String _simpleValue2 = 'Menu item value two';
|
||||
final String _simpleValue3 = 'Menu item value three';
|
||||
String _simpleValue;
|
||||
|
||||
void showMenuSelection(String value) {
|
||||
if (<String>[_simpleValue1, _simpleValue2, _simpleValue3].contains(value))
|
||||
_simpleValue = value;
|
||||
showInSnackBar('You selected: $value');
|
||||
}
|
||||
|
||||
void showInSnackBar(String value) {
|
||||
Fluttertoast.showToast(
|
||||
msg: value,
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.CENTER,
|
||||
timeInSecForIos: 1,
|
||||
backgroundColor: Colors.grey,
|
||||
textColor: Colors.white);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_simpleValue = _simpleValue2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
ListTile(
|
||||
title: const Text('An item with a context menu button'),
|
||||
trailing: PopupMenuButton<String>(
|
||||
padding: EdgeInsets.zero,
|
||||
onSelected: showMenuSelection,
|
||||
itemBuilder: (BuildContext context) => <PopupMenuItem<String>>[
|
||||
PopupMenuItem<String>(
|
||||
value: _simpleValue1,
|
||||
child: const Text('Context menu item one')),
|
||||
const PopupMenuItem<String>(
|
||||
enabled: false, child: Text('A disabled menu item')),
|
||||
PopupMenuItem<String>(
|
||||
value: _simpleValue3,
|
||||
child: const Text('Context menu item three')),
|
||||
],
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('An item with a sectioned menu'),
|
||||
trailing: PopupMenuButton<String>(
|
||||
padding: EdgeInsets.zero,
|
||||
onSelected: showMenuSelection,
|
||||
itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
|
||||
const PopupMenuItem<String>(
|
||||
value: 'Preview',
|
||||
child: ListTile(
|
||||
leading: Icon(Icons.visibility),
|
||||
title: Text('Preview'))),
|
||||
const PopupMenuItem<String>(
|
||||
value: 'Share',
|
||||
child: ListTile(
|
||||
leading: Icon(Icons.person_add),
|
||||
title: Text('Share'))),
|
||||
const PopupMenuItem<String>(
|
||||
value: 'Get Link',
|
||||
child: ListTile(
|
||||
leading: Icon(Icons.link),
|
||||
title: Text('Get link'))),
|
||||
const PopupMenuDivider(),
|
||||
const PopupMenuItem<String>(
|
||||
value: 'Remove',
|
||||
child: ListTile(
|
||||
leading: Icon(Icons.delete), title: Text('Remove')))
|
||||
],
|
||||
),
|
||||
),
|
||||
PopupMenuButton<String>(
|
||||
padding: EdgeInsets.zero,
|
||||
initialValue: _simpleValue,
|
||||
onSelected: showMenuSelection,
|
||||
child: ListTile(
|
||||
title: const Text('An item with a simple menu'),
|
||||
subtitle: Text(_simpleValue)),
|
||||
itemBuilder: (BuildContext context) => <PopupMenuItem<String>>[
|
||||
PopupMenuItem<String>(
|
||||
value: _simpleValue1, child: Text(_simpleValue1)),
|
||||
PopupMenuItem<String>(
|
||||
value: _simpleValue2, child: Text(_simpleValue2)),
|
||||
PopupMenuItem<String>(
|
||||
value: _simpleValue3, child: Text(_simpleValue3))
|
||||
],
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('An item with a sectioned menu'),
|
||||
trailing: PopupMenuButton<String>(
|
||||
padding: EdgeInsets.zero,
|
||||
onSelected: showMenuSelection,
|
||||
itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
|
||||
const PopupMenuItem<String>(
|
||||
value: 'Preview',
|
||||
child: ListTile(
|
||||
leading: Icon(Icons.visibility),
|
||||
title: Text('Preview')
|
||||
)
|
||||
),
|
||||
const PopupMenuItem<String>(
|
||||
value: 'Share',
|
||||
child: ListTile(
|
||||
leading: Icon(Icons.person_add),
|
||||
title: Text('Share')
|
||||
)
|
||||
),
|
||||
const PopupMenuItem<String>(
|
||||
value: 'Get Link',
|
||||
child: ListTile(
|
||||
leading: Icon(Icons.link),
|
||||
title: Text('Get link')
|
||||
)
|
||||
),
|
||||
const PopupMenuDivider(),
|
||||
const PopupMenuItem<String>(
|
||||
value: 'Remove',
|
||||
child: ListTile(
|
||||
leading: Icon(Icons.delete),
|
||||
title: Text('Remove')
|
||||
)
|
||||
)
|
||||
]
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
47
lib/widgets/components/Menu/PopupMenuButton/index.dart
Normal file
47
lib/widgets/components/Menu/PopupMenuButton/index.dart
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* @Author: 一凨
|
||||
* @Date: 2018-12-27 14:43:50
|
||||
* @Last Modified by: 一凨
|
||||
* @Last Modified time: 2018-12-27 15:44:31
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../common/widget_demo.dart';
|
||||
import './demo.dart';
|
||||
|
||||
const String content0 = '''
|
||||
### **简介**
|
||||
> 一个提供菜单栏弹出对话框的按钮
|
||||
- 点击的时候弹出菜单栏对话框,当选择其中一项后会调用 onSelected方法。传递其所选的菜单项的值
|
||||
- 可以提供child子widget或者一个icon给它,但是并不能两者都提供
|
||||
- 如果什么都没有提供给 PopupMenuButton ,则会根据运行平台创建一个overflow icon
|
||||
|
||||
''';
|
||||
|
||||
const String content1 = '''
|
||||
### **基本用法**
|
||||
> PopupMenuButton 通常配合 PopupMenuItem 一起使用
|
||||
- enabled 标识当前item是否可点击
|
||||
- PopupMenuItem 可以在child中传入带有Icon的widget
|
||||
- 可以指定 PopupMenuButton 的 初始值 initialValue
|
||||
''';
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Menu/PopupMenuButton';
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
contentList: [
|
||||
content0,
|
||||
content1,
|
||||
PopupMenuButtonDemo(),
|
||||
],
|
||||
codeUrl: 'components/Menu/PopupMenuButton/demo.dart',
|
||||
docUrl: 'https://docs.flutter.io/flutter/material/PopupMenuButton-class.html',
|
||||
title: 'PopupMenuButton',
|
||||
);
|
||||
}
|
||||
}
|
69
lib/widgets/components/Menu/PopupMenuDivider/demo.dart
Normal file
69
lib/widgets/components/Menu/PopupMenuDivider/demo.dart
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* @Author: 一凨
|
||||
* @Date: 2018-12-27 15:45:26
|
||||
* @Last Modified by: 一凨
|
||||
* @Last Modified time: 2018-12-27 15:45:26
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
|
||||
|
||||
|
||||
class PopupMenuDividerDemo extends StatelessWidget {
|
||||
|
||||
|
||||
void showInSnackBar(String value) {
|
||||
Fluttertoast.showToast(
|
||||
msg: value,
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.CENTER,
|
||||
timeInSecForIos: 1,
|
||||
backgroundColor: Colors.grey,
|
||||
textColor: Colors.white);
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
child:ListTile(
|
||||
title: const Text('An item with a sectioned menu'),
|
||||
trailing: PopupMenuButton<String>(
|
||||
padding: EdgeInsets.zero,
|
||||
onSelected: showInSnackBar,
|
||||
itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
|
||||
const PopupMenuItem<String>(
|
||||
value: 'Preview',
|
||||
child: ListTile(
|
||||
leading: Icon(Icons.visibility),
|
||||
title: Text('Preview')
|
||||
)
|
||||
),
|
||||
const PopupMenuItem<String>(
|
||||
value: 'Share',
|
||||
child: ListTile(
|
||||
leading: Icon(Icons.person_add),
|
||||
title: Text('Share')
|
||||
)
|
||||
),
|
||||
const PopupMenuItem<String>(
|
||||
value: 'Get Link',
|
||||
child: ListTile(
|
||||
leading: Icon(Icons.link),
|
||||
title: Text('Get link')
|
||||
)
|
||||
),
|
||||
const PopupMenuDivider(),
|
||||
const PopupMenuItem<String>(
|
||||
value: 'Remove',
|
||||
child: ListTile(
|
||||
leading: Icon(Icons.delete),
|
||||
title: Text('Remove')
|
||||
)
|
||||
)
|
||||
]
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
44
lib/widgets/components/Menu/PopupMenuDivider/index.dart
Normal file
44
lib/widgets/components/Menu/PopupMenuDivider/index.dart
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* @Author: 一凨
|
||||
* @Date: 2018-12-27 14:51:58
|
||||
* @Last Modified by: 一凨
|
||||
* @Last Modified time: 2018-12-27 15:55:22
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../common/widget_demo.dart';
|
||||
import './demo.dart';
|
||||
|
||||
const String content0 = '''
|
||||
### **简介**
|
||||
> 一个提供菜单栏弹出对话框中每一项的水平线
|
||||
- 配合 PopupMenuItem 和 PopupMenuButton 使用
|
||||
- PopupMenuDivider 可以调整高度,但无法调整颜色
|
||||
''';
|
||||
|
||||
const String content1 = '''
|
||||
### **基本用法**
|
||||
> 此widget通过调整Divider widget 来适应于弹出菜单中
|
||||
- 在 PopupMenuButton 中直接 new PopupMenuDivider() 即可
|
||||
''';
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Menu/PopupMenuDivider';
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
contentList: [
|
||||
content0,
|
||||
content1,
|
||||
PopupMenuDividerDemo(),
|
||||
],
|
||||
codeUrl: 'components/Menu/PopupMenuDivider/demo.dart',
|
||||
docUrl:
|
||||
'https://docs.flutter.io/flutter/material/PopupMenuDivider-class.html',
|
||||
title: 'PopupMenuDivider',
|
||||
);
|
||||
}
|
||||
}
|
41
lib/widgets/components/Menu/PopupMenuEntry/index.dart
Normal file
41
lib/widgets/components/Menu/PopupMenuEntry/index.dart
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* @Author: 一凨
|
||||
* @Date: 2018-12-27 14:51:58
|
||||
* @Last Modified by: 一凨
|
||||
* @Last Modified time: 2018-12-27 16:06:20
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../common/widget_demo.dart';
|
||||
import '../PopupMenuDivider/demo.dart';
|
||||
|
||||
const String content0 = '''
|
||||
### **简介**
|
||||
> Material 风格中 弹出菜单的一个基类
|
||||
- 如果需要创建一个显示弹出菜单的按钮,请考虑使用 PopupMenuButton.
|
||||
''';
|
||||
|
||||
const String content1 = '''
|
||||
### **基本用法**
|
||||
- PopupMenuDivider 是一条水平分割线,注意数组要使用父类 PopupMenuEntry,配合其他 item 样式共同使用
|
||||
''';
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Menu/PopupMenuEntry';
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
contentList: [
|
||||
content0,
|
||||
content1,
|
||||
PopupMenuDividerDemo()
|
||||
],
|
||||
docUrl: 'https://docs.flutter.io/flutter/material/PopupMenuEntry-class.html',
|
||||
codeUrl: 'components/Menu/PopupMenuEntry/demo.dart',
|
||||
title: 'PopupMenuEntry',
|
||||
);
|
||||
}
|
||||
}
|
41
lib/widgets/components/Menu/PopupMenuItem/index.dart
Normal file
41
lib/widgets/components/Menu/PopupMenuItem/index.dart
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* @Author: xiaojia.dxj
|
||||
* @Date: 2018-12-29 15:04:51
|
||||
* @Last Modified by: xiaojia.dxj
|
||||
* @Last Modified time: 2018-12-29 15:07:16
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../common/widget_demo.dart';
|
||||
import '../PopupMenuDivider/demo.dart';
|
||||
|
||||
const String content0 = '''
|
||||
### **简介**
|
||||
> Material 中窗口弹出的菜单
|
||||
- 如果需要创建一个显示弹出菜单的按钮,请考虑使用 PopupMenuButton.
|
||||
''';
|
||||
|
||||
const String content1 = '''
|
||||
### **基本用法**
|
||||
- PopupMenuDivider 是一条水平分割线,注意数组要使用父类 PopupMenuEntry,配合其他 item 样式共同使用
|
||||
''';
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Menu/PopupMenuItem';
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
contentList: [
|
||||
content0,
|
||||
content1,
|
||||
PopupMenuDividerDemo()
|
||||
],
|
||||
docUrl: "https://docs.flutter.io/flutter/material/PopupMenuItem-class.html",
|
||||
codeUrl: 'components/Menu/PopupMenuEntry/demo.dart',
|
||||
title: 'PopupMenuItem',
|
||||
);
|
||||
}
|
||||
}
|
42
lib/widgets/components/Menu/PopupMenuItemState/index.dart
Normal file
42
lib/widgets/components/Menu/PopupMenuItemState/index.dart
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* @Author: xiaojia.dxj
|
||||
* @Date: 2018-12-29 15:04:51
|
||||
* @Last Modified by: xiaojia.dxj
|
||||
* @Last Modified time: 2018-12-29 16:22:06
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../common/widget_demo.dart';
|
||||
import '../PopupMenuDivider/demo.dart';
|
||||
|
||||
const String content0 = '''
|
||||
### **简介**
|
||||
> 这个state 是 PopupMenuItem 子类
|
||||
- 默认情况下,它实现了Material Design弹出菜单项的基本样式和布局,然而这个buidlChild方法可以重写,以调整放置在菜单中的位置。默认它返回PopupMenuItem.child。
|
||||
|
||||
''';
|
||||
|
||||
const String content1 = '''
|
||||
### **基本用法**
|
||||
- PopupMenuDivider 是一条水平分割线,注意数组要使用父类 PopupMenuEntry,配合其他 item 样式共同使用
|
||||
''';
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Menu/PopupMenuItem';
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
contentList: [
|
||||
content0,
|
||||
content1,
|
||||
PopupMenuDividerDemo()
|
||||
],
|
||||
docUrl: "https://docs.flutter.io/flutter/material/PopupMenuItem-class.html",
|
||||
codeUrl: 'components/Menu/PopupMenuEntry/demo.dart',
|
||||
title: 'PopupMenuItem',
|
||||
);
|
||||
}
|
||||
}
|
50
lib/widgets/components/Menu/index.dart
Normal file
50
lib/widgets/components/Menu/index.dart
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* @Author: 一凨
|
||||
* @Date: 2018-12-22 21:01:42
|
||||
* @Last Modified by: 一凨
|
||||
* @Last Modified time: 2018-12-27 14:53:04
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../model/widget.dart';
|
||||
|
||||
import './CheckedPopupMenuItem/index.dart' as CheckedPopupMenuItem;
|
||||
import './DropdownMenuItem/index.dart' as DropdownMenuItem;
|
||||
import './PopupMenuButton/index.dart' as PopupMenuButton;
|
||||
import './PopupMenuDivider/index.dart' as PopupMenuDivider;
|
||||
import './PopupMenuEntry/index.dart' as PopupMenuEntry;
|
||||
import './PopupMenuItem/index.dart' as PopupMenuItem;
|
||||
import './PopupMenuItemState/index.dart' as PopupMenuItemState;
|
||||
|
||||
|
||||
List<WidgetPoint> widgetPoints = [
|
||||
WidgetPoint(
|
||||
name:'CheckedPopupMenuItem',
|
||||
routerName: CheckedPopupMenuItem.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => CheckedPopupMenuItem.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name:'DropdownMenuItem',
|
||||
routerName: DropdownMenuItem.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => DropdownMenuItem.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name:'PopupMenuButton',
|
||||
routerName: PopupMenuButton.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => PopupMenuButton.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name:'PopupMenuDivider',
|
||||
routerName: PopupMenuDivider.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => PopupMenuDivider.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name:'PopupMenuEntry',
|
||||
routerName: PopupMenuEntry.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => PopupMenuEntry.Demo(),
|
||||
),
|
||||
WidgetPoint(
|
||||
name:'PopupMenuItemState',
|
||||
routerName: PopupMenuItemState.Demo.routeName,
|
||||
buildRouter: (BuildContext context) => PopupMenuItemState.Demo(),
|
||||
),
|
||||
];
|
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2018/12/27
|
||||
* Time: 下午6:27
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: BottomNavigationBar 的示例
|
||||
*/
|
||||
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/*
|
||||
* Checkbox 默认按钮的实例
|
||||
* index 当前checkbox 的索引值
|
||||
* */
|
||||
class BottomNavigationBarFullDefault extends StatefulWidget {
|
||||
const BottomNavigationBarFullDefault() : super();
|
||||
@override
|
||||
State<StatefulWidget> createState() => _BottomNavigationBarFullDefault();
|
||||
}
|
||||
|
||||
/*
|
||||
* BottomNavigationBar 默认的实例,有状态
|
||||
* */
|
||||
class _BottomNavigationBarFullDefault extends State {
|
||||
int _currentIndex = 1;
|
||||
|
||||
void _onItemTapped(int index) {
|
||||
setState(() {
|
||||
_currentIndex = index;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BottomNavigationBar(
|
||||
type: BottomNavigationBarType.fixed, // BottomNavigationBarType 中定义的类型,有 fixed 和 shifting 两种类型
|
||||
iconSize: 24.0, // BottomNavigationBarItem 中 icon 的大小
|
||||
currentIndex: _currentIndex, // 当前所高亮的按钮index
|
||||
onTap: _onItemTapped, // 点击里面的按钮的回调函数,参数为当前点击的按钮 index
|
||||
fixedColor: Colors.deepPurple, // 如果 type 类型为 fixed,则通过 fixedColor 设置选中 item 的颜色
|
||||
items: <BottomNavigationBarItem> [
|
||||
BottomNavigationBarItem(
|
||||
title: new Text("Home"), icon: new Icon(Icons.home)),
|
||||
BottomNavigationBarItem(
|
||||
title: new Text("List"), icon: new Icon(Icons.list)),
|
||||
BottomNavigationBarItem(
|
||||
title: new Text("Message"), icon: new Icon(Icons.message)),
|
||||
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* BottomNavigationBar 默认的实例,无状态
|
||||
* */
|
||||
class BottomNavigationBarLessDefault extends StatelessWidget {
|
||||
final widget;
|
||||
final parent;
|
||||
|
||||
const BottomNavigationBarLessDefault([this.widget, this.parent])
|
||||
: super();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BottomNavigationBar(
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2018/12/27
|
||||
* Time: 下午6:28
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: BottomNavigationBar 的示例
|
||||
*/
|
||||
import '../customDemo.dart';
|
||||
import '../../../../routers/application.dart';
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import './demo.dart' as BottomNavigationBarDemo;
|
||||
|
||||
const String _text0 =
|
||||
"""### **简介**
|
||||
> BottomNavigationBar “底部导航栏”,
|
||||
- 显示在应用程序底部的导航栏,由文本标签,图标或两者形式的多个项目组成。
|
||||
- 它提供了应用程序顶级视图之间的快速导航。
|
||||
""";
|
||||
|
||||
|
||||
const String _text1 =
|
||||
"""### **基本用法**
|
||||
> BottomNavigationBar 底部导航栏通常与Scaffold结合使用
|
||||
- 它作为Scaffold.bottomNavigationBar参数。
|
||||
- BottomNavigationBar金支持0-4个之间个底部按钮数量,超出4个系统将会报异常。
|
||||
- 默认0-3个底部按钮数量时,BottomNavigationBar采用fixed的模式摆放底部按钮,当超过4个时默认使用 BottomNavigationBarType.shifting 模式摆放底部按钮
|
||||
- 下面的底部导航即是效果。
|
||||
""";
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Navigation/BottomNavigationBar';
|
||||
|
||||
@override
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CustomDemo(
|
||||
title: 'BottomNavigationBar',
|
||||
codeUrl: '${Application.github['widgetsURL']}components/Navigation/BottomNavigationBar/demo.dart',
|
||||
child: allCheckboxs(context, this),
|
||||
docUrl: 'https://docs.flutter.io/flutter/material/BottomNavigationBar-class.html',
|
||||
bottomNaviBar:BottomNavigationBarDemo.BottomNavigationBarFullDefault()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 所有的 BottomNavigationBar widget
|
||||
* context: 运行上下文
|
||||
* that: 指向有状态的 StatefulWidget
|
||||
*/
|
||||
Widget allCheckboxs(BuildContext context, _DemoState that) {
|
||||
return Container(
|
||||
//padding: new EdgeInsets.only(bottom: 20.0, top: 20.0, left: 0, right: 0),
|
||||
child: Column(
|
||||
//mainAxisSize: MainAxisSize.max,
|
||||
children: <Widget>[
|
||||
MarkdownBody(data: _text0),
|
||||
textAlignBar(_text1),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
//BottomNavigationBarDemo.BottomNavigationBarFullDefault();
|
||||
],
|
||||
),
|
||||
SizedBox(width: 20.0), // 间距
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* 带align的text
|
||||
* */
|
||||
Widget textAlignBar(String txt) {
|
||||
return new Align(
|
||||
alignment: FractionalOffset.centerLeft,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
SizedBox(height: 20.0),
|
||||
MarkdownBody(data: txt)
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2019/1/1
|
||||
* Time: 下午10:00
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: BottomNavigationBarItem 的示例
|
||||
*/
|
||||
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/*
|
||||
* Checkbox 默认按钮的实例
|
||||
* index 当前checkbox 的索引值
|
||||
* */
|
||||
class BottomNavigationBarItemFullDefault extends StatefulWidget {
|
||||
const BottomNavigationBarItemFullDefault() : super();
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _BottomNavigationBarItemFullDefault();
|
||||
}
|
||||
|
||||
/*
|
||||
* BottomNavigationBarItem 默认的实例,有状态
|
||||
* */
|
||||
class _BottomNavigationBarItemFullDefault extends State {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* BottomNavigationBarItem 默认的实例,无状态
|
||||
* */
|
||||
class BottomNavigationBarItemLessDefault extends StatelessWidget {
|
||||
final widget;
|
||||
final parent;
|
||||
|
||||
const BottomNavigationBarItemLessDefault([this.widget, this.parent])
|
||||
: super();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new SizedBox(
|
||||
height: 100,
|
||||
child: Scaffold(
|
||||
bottomNavigationBar: new BottomNavigationBar(items: [
|
||||
new BottomNavigationBarItem(
|
||||
icon: new Icon(Icons.laptop_chromebook),
|
||||
title: new Text("主页"),
|
||||
backgroundColor: Colors.red
|
||||
),
|
||||
new BottomNavigationBarItem(
|
||||
icon: new Icon(Icons.list), title: new Text("分类"),backgroundColor: Colors.grey),
|
||||
new BottomNavigationBarItem(
|
||||
icon: new Icon(Icons.local_grocery_store), title: new Text("购物车")),
|
||||
new BottomNavigationBarItem(icon: new Icon(Icons.person), title: new Text("我的"))
|
||||
],
|
||||
//onTap: onTap,
|
||||
//currentIndex: page
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//backgroundColor: Colors.grey,
|
||||
//
|
||||
//// body: new PageView(
|
||||
////
|
||||
//// children: [
|
||||
//// new Index(),
|
||||
//// new Classify(),
|
||||
//// new Shopping(),
|
||||
//// new Myself()
|
||||
//// ],
|
||||
////
|
||||
//// controller: pageController,
|
||||
//// onPageChanged: onPageChanged
|
||||
//// ),
|
||||
//
|
@ -0,0 +1,89 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: ryan
|
||||
* Date: 2019/1/1
|
||||
* Time: 下午9:55
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: BottomNavigationBarItem 的示例
|
||||
*/
|
||||
import '../../../../common/widget-demo.dart';
|
||||
import '../../../../routers/application.dart';
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import './demo.dart' as BottomNavigationBarItemDemo;
|
||||
|
||||
const String _Text0 =
|
||||
"""### **简介**
|
||||
> BottomNavigationBarItem “底部导航应用栏”
|
||||
- material 的 BottomNavigationBar 或带有图标和标题的 iOS主题 CupertinoTabBar 中的交互式按钮。
|
||||
""";
|
||||
|
||||
|
||||
const String _Text1 =
|
||||
"""### **基本用法**
|
||||
> 这个类很少单独使用。通常嵌入在上面的一个底部 bottom navigation widgets 中。
|
||||
""";
|
||||
|
||||
const String _Text2 =
|
||||
"""### **进阶用法**
|
||||
> BottomNavigationBarItem
|
||||
-
|
||||
""";
|
||||
|
||||
class Demo extends StatefulWidget {
|
||||
static const String routeName = '/components/Navigation/BottomNavigationBarItem';
|
||||
|
||||
@override
|
||||
_DemoState createState() => _DemoState();
|
||||
}
|
||||
|
||||
class _DemoState extends State<Demo> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WidgetDemo(
|
||||
title: 'BottomNavigationBarItem',
|
||||
codeUrl: '${Application.github['widgetsURL']}componentss/Bar/BottomNavigationBarItem/demo.dart',
|
||||
child: allCheckboxs(context, this),
|
||||
docUrl: 'https://docs.flutter.io/flutter/widgets/BottomNavigationBarItem-class.html',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 所有的 BottomNavigationBarItem widget
|
||||
* context: 运行上下文
|
||||
* that: 指向有状态的 StatefulWidget
|
||||
*/
|
||||
Widget allCheckboxs(BuildContext context, _DemoState that) {
|
||||
return Container(
|
||||
//padding: new EdgeInsets.only(bottom: 20.0, top: 20.0, left: 0, right: 0),
|
||||
child: Column(
|
||||
//mainAxisSize: MainAxisSize.max,
|
||||
children: <Widget>[
|
||||
MarkdownBody(data: _Text0),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
MarkdownBody(data: _Text1),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
BottomNavigationBarItemDemo.BottomNavigationBarItemLessDefault(),
|
||||
SizedBox(height: 20.0), // 间距
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* 带align的text
|
||||
* */
|
||||
Widget textAlignBar(String txt) {
|
||||
return new Align(
|
||||
alignment: FractionalOffset.centerLeft,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
SizedBox(height: 20.0),
|
||||
MarkdownBody(data: txt)
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user