flutter實戰4:新聞列表的懶載入和下拉手勢重新整理

燃燒的魚丸發表於2018-04-07

上一篇我們實現了新聞列表,但在網路不好的時候列表會白屏,因此為了提高使用體驗,往列表中加入懶載入效果。其次,引入一個Flutter內建的手勢控制元件,用於支援下拉重新整理列表的效果如下圖:

懶載入和下拉重新整理手勢

Flutter將非同步執行也進行了控制元件化處理,即:Future。不過我還沒完全掌握怎麼使用Future,只能把學到的跟大家分享一下,以後玩6了再補充。前面的分享中大家應該也接觸並使用到了Future,比如IO操作的HTTP請求。除了通過asyncawait關鍵字以外,還可以用一個更方便的控制元件,可生成程式碼在非同步執行時間軸上的快照,並按照自己的需求觸發需要的事件,這就是FutureBuilder控制元件。

FutureBuilder用法和實現

先簡單講講FutureBuilder

//FutureBuilder控制元件
new FutureBuilder<String>(
  future: _calculation, // 使用者定義的需要非同步執行的程式碼,型別為Future<String>或者null的變數或函式
  builder: (BuildContext context, AsyncSnapshot<String> snapshot) {      //snapshot就是_calculation在時間軸上執行過程的狀態快照
    switch (snapshot.connectionState) {
      case ConnectionState.none: return new Text('Press button to start');    //如果_calculation未執行則提示:請點選開始
      case ConnectionState.waiting: return new Text('Awaiting result...');  //如果_calculation正在執行則提示:載入中
      default:    //如果_calculation執行完畢
        if (snapshot.hasError)    //若_calculation執行出現異常
          return new Text('Error: ${snapshot.error}');
        else    //若_calculation執行正常完成
          return new Text('Result: ${snapshot.data}');
    }
  },
)
複製程式碼

FutureBuilder通過子屬性future獲取使用者需要非同步處理的程式碼,用builder回撥函式暴露出非同步執行過程中的快照。我們通過builder的引數snapshot暴露的快照屬性,定義好對應狀態下的處理程式碼,即可實現非同步執行時的互動邏輯。

看起來似乎有點暈菜,可能還是不知道怎麼用,讓我們看看下面這段實戰程式碼:

FutureBuilder實戰程式碼

  • snapshot.connectionState就是非同步函式get(widget.newsType)的執行狀態,使用者通過定義在ConnectionState.noneConnectionState.waiting狀態下,輸出一個居中(Center)顯示並且內建文字(Text)為_loading..._的卡片(Card),其意義即:當非同步函式get(widget.newsType)未執行和正在執行時,螢幕正中央顯示文字:loading...

  • get(widget.newsType)執行完畢後,snapshot.connectionState的值即變為ConnectionState.done,此時即可輸出根據HTTP請求獲取到的資料生成對應的ListItem。由於ConnectionState.done是除了ConnectionState.noneConnectionState.waiting以外的唯一值,所以程式碼中在switch下用default即可。

由於通過FutureBuilder內的builder()函式即可操控控制元件的狀態和重繪,碼農不必通過自己寫非同步狀態的判斷和多次使用setState()實現頁面上載入中載入完成顯示效果的切換,因為FutureBuilder內部自帶了執行setState()的方法。

懶載入就這麼輕鬆實現了,玩家還可以自己定義更漂亮的載入中的提示控制元件,FutureBuilder的控制元件化非常的純淨和徹底,它只做非同步監視,沒有內建視覺化控制元件,視覺上的處理完全交由玩家自行定義,可玩度非常高,相信很多IO操作都會用到這個控制元件。

RefreshIndicator的用法和實現

RefreshIndicator是Flutter基於Material設計語言內建的控制元件,集合了下拉手勢、載入指示器和重新整理操作一體,可玩性比FutureBuilder差了一大截,不過大家也用過Material設計語言的其他控制元件,視覺效果也不賴的,先看看控制元件的基本結構:

RefreshIndicator(
  //RefreshIndicator的子元素必須是一個可以滾動的控制元件
  //如果你遇到不符合條件的控制元件,請將其用可以滾動的控制元件(如ListView、PageView等)包裝一下
  child: new ScrollableWidget,    
  onRefresh: loadData,    //onRefresh的回撥必須是一個Future<Null>型別
)
複製程式碼

這個控制元件的使用非常簡單,相信大家很容易理解,然後我們來看看實戰程式碼:

RefreshIndicator實戰程式碼

是不是很簡單,如果你想對某個控制元件實現下拉手勢重新整理的效果,用RefreshIndicator包裝一下,分分鐘搞定。但需要注意的就是onRefresh的回撥函式必須是Future<Null>型別,另外其回撥函式內部,必須要有setState()控制程式碼,哪怕你不更新任何狀態值,如果沒有這句,子控制元件就不會發生重新整理動作,這樣明顯是消耗效能且非常不優雅的,奈何現在還不夠強大的我找不到其他辦法廢掉setState(),暫時先滿足基本要求吧,至於什麼時候解決這個問題,應該是屬於家祭無忘告乃翁系列事件吧~

最後

全篇的程式碼,大家可以到我的Git中下載,將來我還會在這個APP中新增更多的功能和程式碼註釋,喜歡的同學也可以star我一下,哈哈哈,讓我也浪一波。

本篇內容不多,對Future慾望強烈的玩家,完全可以在IDE中Ctrl+滑鼠左鍵點選程式碼中的FutureFutureBuilder關鍵字,到Flutter原始碼中檢視其原理和說明,當然了,和官網的內容是一模一樣的。

官方文件更新很頻繁,看得出谷歌推Flutter真的是誠意滿滿,喜歡Flutter的小夥伴,也可以加入到Flutter圈子flutter 中文社群(官方QQ群:338252156),群裡有前後端及全棧各路大神鎮場子,加入進來沒事就寫寫APP掙點外快(這個真的有),順便翻譯翻譯官方英文原稿拉一票粉絲,一舉多得何樂而不為呢。

相關文章