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;
}
本篇完~