Android开发Android开发Android开发经验谈

阿里 Flutter-go 项目拆解笔记(六)

2019-03-13  本文已影响9人  d74f37143a31

Flutter-go 项目地址是:https://github.com/alibaba/flutter-go

上文 我们分析了 第二个 Tab 页面,主要分析了 数据列表的渲染,以及小猫头UI和网格布局的实现

这篇文章主要拆解 第三个Tab页面(组件收藏)。对应的collection_page.dart文件的路径如下:'package:flutter_go/views /collection_page/collection_page.dart';

有数据的UI.PNG

下图是整理后的collection_page.dart文件主要的内容:

组件收藏.png

使用 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;
    }

本篇完~

上一篇下一篇

猜你喜欢

热点阅读