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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ITxiaodong/article/details/88411582

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

上文 我们分析了first_page.dart文件,分析了首页的实现效果主要有 免责弹窗、Banner(小圆点,无限循环),信息流(上拉加载,下拉刷新)

这篇文章主要拆解 搜索功能,也就是拆解项目到目前为止比较难的一个功能。搜索功能对应的search_input.dart文件的路径如下:'package:flutter_go/components/search_input.dart';

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

老实说,搜索功能我研究的还不是很透,可能也是没达到研究透的能力,目前先分析到这,待分析完整个项目后着手开发 玩Android项目 应该会有更深刻的理解吧~

搜索功能.png

从图中我们可以知道 搜索功能 包含了哪些操作:

  • 首页的搜索框
  • 搜索结果展示
  • 联想搜索
  • 历史搜索

首页的搜索框

UI 展示和页面跳转

UI展示代码:

 @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, 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,
            ),
          ),
        ],
      ),
    );
  }

点击首页搜索跳转到搜索页面

  _showMaterialSearch(BuildContext context) {
      /// 点击首页搜索后,跳转搜索页面
      Navigator.of(context)
        .push(_buildMaterialSearchPage(context))
        .then((dynamic value) {
      if (value != null) {
        _formFieldKey.currentState.didChange(value);
        widget.onSelect(value);
      }
    });
  }

历史搜索

在跳转搜索页面的时候,先判断是否有 历史搜索 记录,有则显示,没有则提示 当前历史面板为空

扫描二维码关注公众号,回复: 6518760 查看本文章
  /// 搜索结果显示
  Widget buildBody(List results) {
    if (_criteria.isEmpty) {
      return History();
    } else 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("暂无数据"));
  }

History 组件中,先从SP获取搜索的历史记录,然后将结果展示在 Chip 组件上,点击每一个历史记录都跳转到对应Widget的详情页面:

onTap: () {
  Application.router.navigateTo(context, "${value.targetRouter}", transition: TransitionType.inFromRight);
},

搜索结果展示

在文章顶部的图中,我们可以找到显示搜索结果的方法是_buildMaterialSearchPage,在_buildMaterialSearchPage中使用了MaterialPageRoute,并且返回了MaterialSearch组件

MaterialPageRoute是一种模态路由,可以通过平台自适应过渡来切换屏幕。对于Android,页面推送过渡时向上滑动页面,并将其淡入淡出。

所以在点击搜索的搜索框之后进入搜索页面会有一个向上滑动的切换动画。

MaterialSearch构造方法中对 返回结果 进行了排序、过滤、限制数量。

  /// 搜索结果页面
  _buildMaterialSearchPage(BuildContext context) {
    return new _MaterialSearchPageRoute<T>(
        settings: new RouteSettings(
          name: 'material_search',
          isInitialRoute: false,
        ),
        builder: (BuildContext context) {
          return new Material(
            child: new MaterialSearch<T>(
              placeholder: widget.placeholder,
              results: widget.results,
              getResults: widget.getResults,
              filter: widget.filter,
              sort: widget.sort,
              onSelect: (dynamic value) => Navigator.of(context).pop(value),
            ),
          );
        });
  }

联想搜索

可以看到源码中new SearchInput((value)中的value表示的是输入的数据,当数据不为''的时候就会去数据库中查找 widget

  /// 联想搜索,显示搜索结果列表
  Widget buildSearchInput(BuildContext context) {
    return new SearchInput((value) async {
      if (value != '') {
        // 去数据库中查找 widget 
        List<WidgetPoint> list = await widgetControl.search(value);

        return list
            .map((item) => new MaterialSearchResult<String>(
                  value: item.name,
                  icon: WidgetName2Icon.icons[item.name] ?? null,
                  text: 'widget',
                  onTap: () {
                    // item 点击
                    onWidgetTap(item, context);
                  },
                ))
            .toList();
      } else {
        return null;
      }
    }, (value) {}, () {});
  }

本篇完~

猜你喜欢

转载自blog.csdn.net/ITxiaodong/article/details/88411582