前言
在flutter的開發(fā)中,經(jīng)常會遇到ListView
的上下拉加載的業(yè)務(wù)需求,我也嘗試了對該需求的封裝,地址https://github.com/zhahao/auto_refresh_list_view.
由于flutter
是響應(yīng)式的,如果要改變UI的顯示,一般會通過修改成員變量的值,再調(diào)用setState
方法,讓state類
重新調(diào)用build
方法.根據(jù)成員變量的值返回不同的widget
.AutoRefreshListView
內(nèi)部封裝了RefreshIndicator.child
為ListView.builder()
作為主要widget.通過_state
來控制ListView
顯示不同狀態(tài)的視圖.
設(shè)計模式
使用MVP的設(shè)計模式,將AutoRefreshListView
功能拆分出來以下三個部分,并分別由不同Presenter提供實現(xiàn).
- 狀態(tài)視圖展示
- 數(shù)據(jù)的提供
- Item展示
功能實現(xiàn)
AutoRefreshListView內(nèi)部功能實現(xiàn)
上拉
通過ListView
的ScrollController
來判斷
_listScrollController.addListener(() {
var maxScroll = _listScrollController.position.maxScrollExtent;
var pixel = _listScrollController.position.pixels;
if (maxScroll == pixel && _loadingFlag == false) {
/// 先將加載中的flag置為true,防止重復(fù)執(zhí)行上拉邏輯
_loadingFlag = true;
/// 滾動到底了,需要執(zhí)行上拉操作
}
});
下拉
使用RefreshIndicator.onRefresh
來監(jiān)聽下拉,一旦手指向下拖拽ListView到一定范圍,就會觸發(fā)onRefresh
回調(diào).這個時候一般會去請求網(wǎng)絡(luò)數(shù)據(jù),請求回來之后需要調(diào)用setState
,RefreshIndicator會被重新build
,下拉箭頭就會消失.
偽代碼:
RefreshIndicator(
child: ListView.builder(itemBuilder: null),
onRefresh: () async{
/// 1.請求網(wǎng)絡(luò)數(shù)據(jù)
var response = await fetchNetworkData();
/// 2.1如果成功,刪除之前的數(shù)據(jù)緩存并存儲請求回來的數(shù)據(jù)
/// 2.2如果失敗,提示失敗
if (response.success) {
cleanData();
restoreData();
setState((){});
}else {
showErrorDialog();
}
});
AutoRefreshListView交由Presenter的實現(xiàn)
狀態(tài)視圖展示
使用一個_state
將整個ListView的狀態(tài)進行記錄,一旦_state
發(fā)生改變就調(diào)用setState
方法.切換build
方法返回的widget
.該功能由RefreshListStateViewIPresenter
提供.
enum _AutoRefreshListViewState {
/// 第一次進入的時候正在加載數(shù)據(jù)
loadingFirstPage,
/// 第一次進入加載數(shù)據(jù)失敗
errorOnLoadFirstPage,
/// 第一次進入加載數(shù)據(jù)為空
emptyOnLoadFirstPage,
/// 沒有更多數(shù)據(jù)
loadCompletedNoMoreData,
/// 有更多數(shù)據(jù)
loadCompletedHasMoreData,
/// 加載更多時失敗
errorOnLoadMoreData,
/// 正在加載更多
loadingMoreData,
}
數(shù)據(jù)的提供
由RefreshListViewDataIPresenter
負責提供,抽象了幾個方法,主要包括
- 獲取數(shù)據(jù)
- 清空所有數(shù)據(jù),根據(jù)需求可重寫
- 添加新數(shù)據(jù)
...
AutoRefreshListView
負責處理RefreshListViewDataIPresenter
和RefreshListStateViewIPresenter
之間的邏輯關(guān)系.
Item展示
使用list_view_item_builder三方實現(xiàn),該庫提供了與iOS的UITableview基本一致的delegate
和dataSource
方法.非常方便的構(gòu)建Listview
的item
.且對該庫進行了presenter
處理,由RefreshListViewItemIPresenter
提供item
的實現(xiàn).
總結(jié)
感覺MVP的設(shè)計模式在flutter還是可以使用的,提高代碼邏輯的復(fù)用性.而且dart
支持多繼承,那么所有的presenter
都可以使用with
語法聚合在一個類里面實現(xiàn).這樣對于簡單的邏輯使用也很方便.