阿里 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的源碼中也找到使用的步驟。

  1. 導包,然後new EventBus
在 pubspec.ycaml 文件下添加:
dependencies:
    event_bus: ^1.0.1

在 collection_page.dart 文件下添加:
final eventBus = new EventBus();
// 賦值給全局對象,之後可以直接調用
ApplicationEvent.event = eventBus;
  1. 定義一個類 CollectionEvent
class CollectionEvent{
  final String widgetName;
  final String router;
  final bool isRemove;
  // token uid...
  CollectionEvent(this.widgetName,this.router,this.isRemove);
}
  1. 註冊
@override
  void initState() {
    super.initState();
    _getList();
    ApplicationEvent.event.on<CollectionEvent>().listen((event) {
      _getList();
    });
  }
  1. 在收藏或者取消收藏的地方發送消息,例如這裏在詳情頁面發起的消息
if (ApplicationEvent.event != null) {
     ApplicationEvent.event.fire(CollectionEvent(widget.title, _router, true));
}

收藏的操作

這裏收藏的操作是封裝在CollectionControlModel中的,之前也文章也使用過數庫的操作,項目中使用的數據庫是sqflite,這也是一個第三方關係型數據庫,文檔地址:https://pub.dartlang.org/packages/sqflite

在使用的時候直接new CollectionControlModel()得到該對象之後就可以進行一系列的操作了。比如 收藏的插入,收藏的取消,收藏列表的獲取

這裏也簡單的以獲取收藏列表爲例來了解一下sqflite數據庫的使用。

  1. 導包
在 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");
}

  1. 使用 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};
  }
}
  1. 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);
  }
  1. 調用,例如獲取收藏列表的代碼如下:
  // 獲取全部的收藏
  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;
  }

頁面渲染

頁面其實就是使用了ListViewListTile去實現

這裏區分了收藏的是否是鏈接還是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;
    }

本篇完~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章