阿里 Flutter-go 專案拆解筆記(四)
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); } }); }
歷史搜尋
在跳轉搜尋頁面的時候,先判斷是否有 歷史搜尋 記錄,有則顯示,沒有則提示 當前歷史面板為空
/// 搜尋結果顯示 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) {}, () {}); }
本篇完~