阿里 Flutter-go 项目拆解笔记(六)
Flutter-go 项目地址是:https://github.com/alibaba/flutter-go
上文 我们分析了 第二个 Tab 页面,主要分析了 数据列表的渲染,以及小猫头UI
和网格布局的实现
这篇文章主要拆解 第三个Tab页面(组件收藏)。对应的collection_page.dart
文件的路径如下:'package:flutter_go/views /collection_page/collection_page.dart';
下图是整理后的collection_page.dart
文件主要的内容:
使用 EventBus 监听数据
这里使用了一个库
event_bus
,通过这个库我们可以监听数据的变化来进行对应的操作,比如这里监听收藏数据如果为空则显示空布局,不为空且数据有改变,则去数据库获取最新数据。
EventBus
的地址是:https://pub.dartlang.org/packages/event_bus,
如果想搜索更多的第三方库可浏览这个网站:https://pub.dartlang.org/flutter/packages/
EventBus
的使用方式在官方文档中也介绍了,这里我从flutter-go
的源码中也找到使用的步骤。
- 导包,然后
new EventBus
在 pubspec.ycaml 文件下添加:
dependencies:
event_bus: ^1.0.1
在 collection_page.dart 文件下添加:
final eventBus = new EventBus();
// 赋值给全局对象,之后可以直接调用
ApplicationEvent.event = eventBus;
- 定义一个类
CollectionEvent
class CollectionEvent{
final String widgetName;
final String router;
final bool isRemove;
// token uid...
CollectionEvent(this.widgetName,this.router,this.isRemove);
}
- 注册
@override
void initState() {
super.initState();
_getList();
ApplicationEvent.event.on<CollectionEvent>().listen((event) {
_getList();
});
}
- 在收藏或者取消收藏的地方发送消息,例如这里在详情页面发起的消息
if (ApplicationEvent.event != null) {
ApplicationEvent.event.fire(CollectionEvent(widget.title, _router, true));
}
收藏的操作
这里收藏的操作是封装在
CollectionControlModel
中的,之前也文章也使用过数库的操作,项目中使用的数据库是sqflite
,这也是一个第三方关系型数据库,文档地址:https://pub.dartlang.org/packages/sqflite。
在使用的时候直接new CollectionControlModel()
得到该对象之后就可以进行一系列的操作了。比如 收藏的插入,收藏的取消,收藏列表的获取
这里也简单的以获取收藏列表为例来了解一下sqflite
数据库的使用。
- 导包
在 pubspec.ycaml 文件下添加:
dependencies:
sqflite: ^0.12.1
在`provider.dart`文件下添加:
import 'package:sqflite/sqflite.dart';
// 创建一个数据库,在 provider.dart 文件的 init 方法中
String databasesPath = await getDatabasesPath();
String path = join(databasesPath, 'flutter.db');
print(path);
try {
db = await openDatabase(path);
} catch (e) {
print("Error $e");
}
- 使用
SQL helpers
,可以减少我们写SQL
语句错误的发生。
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};
}
}
- 在
sql.dart
中封装了插入、删除,获取列表等操作
,例如根据条件查询结果。
Future<List> getByCondition({Map<dynamic, dynamic> conditions}) async {
if (conditions == null || conditions.isEmpty) {
return this.get();
}
String stringConditions = '';
int index = 0;
conditions.forEach((key, value) {
if (value == null) {
return ;
}
if (value.runtimeType == String) {
stringConditions = '$stringConditions $key = "$value"';
}
if (value.runtimeType == int) {
stringConditions = '$stringConditions $key = $value';
}
if (index >= 0 && index < conditions.length -1) {
stringConditions = '$stringConditions and';
}
index++;
});
// print("this is string condition for sql > $stringConditions");
return await this.query(tableName, where: stringConditions);
}
- 调用,例如获取收藏列表的代码如下:
// 获取全部的收藏
Future<List<Collection>> getAllCollection() async {
// 通过 sql 的条件去查询
List list = await sql.getByCondition();
List<Collection> resultList = [];
list.forEach((item){
print(item);
resultList.add(Collection.fromJSON(item));
});
return resultList;
}
页面渲染
页面其实就是使用了
ListView
的ListTile
去实现
这里区分了收藏的是否是链接还是Widget
控件,然后显示不同的图标
if (_collectionList[index - 1].router.contains('http')) {
if (_collectionList[index - 1].name.endsWith('Doc')) {
_icons = Icons.library_books;
} else {
_icons = Icons.language;
}
} else {
_icons = Icons.extension;
}
本篇完~