上一篇介紹Banner的開發。在大多數應用場景中。banner和ListView通常是一起顯示的。 并且能夠共同滑動。例如如下界面:
創新互聯主要從事成都做網站、網站建設、網頁設計、企業做網站、公司建網站等業務。立足成都服務四川,十多年網站建設經驗,價格優惠、服務專業,歡迎來電咨詢建站服務:18982081108
要實現上圖的界面,直接想到是ListView添加Header。但在Flutter中,ListView 組件相當于RecyclerView,所以添加Header也用RecyclerView的原理:
封裝ListPage組件,list_page.dart
使用及測試:異步加載網絡數據使用
注意: 滾動組件添加: physics: ClampingScrollPhysics() 可以處理IOS系統的物理滾動的效果(即橡皮筋效果)
ListView 是最常用的可滾動組件之一,可以沿一個方向線性排布所有子組件,并且它也支持基于Sliver的延遲構建模型
默認構造函數:
ListView.builder:
ListView.separated:
ListView.separated 可以在生成的列表項之間添加一個分割組件,它比 ListView.builder 多了一個 separatorBuilder 參數,該參數是一個分割組件生成器。
RefreshIndicator 下拉刷新:
RefreshIndicator 是 Material 風格的下拉刷新組件。
CupertinoSliverRefreshControl 下拉刷新:
CupertinoSliverRefreshControl 是 ios 風格的下拉刷新控件。
上拉加載的功能,需要用到 ScrollController + ListView組件:
為了提升用戶體驗,使用三方登錄APP的功能怎么能少呢,但是蘋果的AppStore有一個很變態的要求,接入其他三方登錄的話,要求必須也要接入蘋果登錄。面對這么變態的要求,作為一個有實力的碼農怎么能拒絕呢!
下面為大家介紹一個好用的Flutter插件 Sign in With Apple ,可以幫助我們快速的接入蘋果賬號功能,插件的英文文檔講的比較詳細了,英文好的同學可以直接參閱英文文檔集成。
在項目的 pubspec.yaml 文件中添加sign_in_with_apple插件的依賴,如果您使用的Flutter SDK 1.x版本請添加依賴版本 2.5.4 :
如果您使用的Flutter SDK為2.x,請使用最新版本,當前最新版本 3.0.0
使用XCode打開項目后,按照以下圖片上的步驟添加 Sign in With Apple Capabilities:
成功添加 Sign in With Apple能力后,可以在下面的列表中就代表添加成功了,如下圖:
講道理我起的好長的名字啊,不過文如上題,搜索到這里的兄弟應該都知道我說的是啥情況,正好
~~
我這個方案可能有點笨拙TT,不過自測有效,有其它想法的老哥希望可以幫忙指點一下~
下面進入正題
點進源碼里面看,可以發現他直接繼承了StatelessWidget,那我們就直接看看build方法
可以看到,這里直接返回一個scrollable或者一個子節點是scrollable的InheritedWidget
scrollable是一個StatefulWidget,那我們就看看它的state
首先scrollable持有一個scrollposition對象,是通過其scrollcontroller構建的
在其state的setCanDrag方法中,對其拖動設置了一系列的監聽
這里就可以看出來,當拖動觸發時,就會通過當前scrollable的position生成一個Drag/Hold對象,并調用相應的方法 這個position有幾個子類,我們先隨便看一個實現
可以看到生成了一個ScrollDragController對象,當手勢拖動而調用這個對象的update方法時
可以看到直接調用其委托對象的applyUserOffset方法進行偏移,而這個委托對象根據剛才的drag方法可以得知正是我們scrollable中的position
最后,由position通知其scrollcontext,也就是之前的scrollable進行滑動
具體的滑動流程這里就不細說了,我們只是要知道這個事件是怎么傳遞的就好了,有興趣的老哥可以自行分析
NestedScrollView是一個statefulwidget,那我們就先看看它的build方法
先忽略其他奇奇怪怪的方法,我們發現在我們body的外面,包裹了一層PrimaryScrollController,同時它還持有innerController,這個innerController暫時先不管它是啥
還記不記得在最開始ScrollView的build方法中,生成Scrollable的時候,我們已經見過這個PrimaryScrollController了,再回顧一下
再看看PrimaryScrollController.of(context)
可以看到,在生成scrollable的時候,在primary = true的情況下是會向上查找的,看看有沒有PrimaryScrollController,如果有的話,scrollable使用的controller實際就是nestedscrollview中的innerController了
而之前看過了,scrollable中的position就是scrollcontroller來生成的,那么在這種情況下:
實際上是生成了_NestedScrollPosition并返回給了body中的scrollable
構造方法中有一個參數coordinator 暫時先不管
好了,下面我們在回頭看剛才NestedScrollView的build方法,實際上是生成了一個_NestedScrollViewCustomScrollView,繼承自大名鼎鼎的CustomScrollView,它當然也是scrollview啦,而我們傳給它的controller也是一個_NestedScrollController,不過叫做_outerController,和body中的不是同一個罷了,那么自然這個父scrollview的position也是_NestedScrollPosition。
下面我們按照之前的邏輯,當拖動開始時,就會調用position.drag方法
可以看到,實際上吧方法交給了我們之前多次見到的coordinator來完成,那我們就簡單看一下吧
這里可以看到,他把返回的ScrollDragController的委托者設成了自己
那么自然在拖動的時候,調用的就是coordinator的applyUseroffset方法了 我們分析一下
可以看到,在需要子列表滾動時,是對innerPositions中的所有position調用滑動方法的
而這innerPositions中的position是怎么來的呢?跟蹤一下可以發現是在調用NestedScrollController的attach時添加進來的,如下
因為之前我們看到過,子scrollable中的controller就是這個NestedScrollController,所以在updateopsition時會把舊的detach調,把新生成的position attach進來
另外,在dispose中也會detach
由此我們就知道啦,因為開啟了緩存后就不會調用劃出屏幕的頁面的dispose,自然所有子scrollable的position都存在nestedScrollController里面了,當發生滑動時,遍歷調用positions數組,就導致屏幕外的列表也跟著滑動了~
既然開啟了緩存,手動dispose肯定是沒啥意義的,實際上我們只要在頁面切換過后把未顯示的position 給detach掉就好了。
然鵝,因為flutter不支持反射,子布局傳遞的position我們拿不到,nestedScrollController我們也不能直接拿到=。=
不過有一個對象我們之前見到過,scrollable就是通過他獲取controller的,而position則是傳給了獲取到的controller 就是PrimaryScrollController了,所以我打算在中間第三者插足,對傳遞Position的PrimaryScrollController進行Hook
在使用的時候把子列表添加進去,并設置對應的GlobalKey。
然后監聽Tab切換
以上是我的方案,有問題的話還希望老哥幫忙指正,也希望有其他思路的老哥指點一下~~
上一下Github項目地址 用Flutter寫的WanAndroid 其中用到了這個方案
= =
3
ListView的基礎創建使用有三種方式:
通過默認構造函數來創建列表,應用場景 = 短列表
這種方式創建的列表存在一個問題:對于那些長列表或者需要較昂貴渲染開銷的子組件,即使還沒有出現在屏幕中但仍然會被ListView所創建,這將是一項較大的開銷,使用不當可能引起性能問題甚至卡頓。
長列表
列表子項之間需要分割線
ListView的進階使用主要包括:下拉刷新 上拉加載
在Flutter中,ListView結合RefreshIndicator組件實現下拉刷新
通過包裹一層RefreshIndicator,自定義onRefresh回調方法實現
方式有兩種:
通過ListView.controller屬性可以判斷ListView是否滑動到了底部,再進行上拉加載
NotificationListener是一個Widget,可監聽子Widget發出的Notification
ListView在滑動時中會發出ScrollNotification類型的通知,可通過監聽該通知得到ListView的滑動狀態,判斷是否滑動到了底部,從而進行上拉加載
NotificationListener有一個onNotification屬性,定義了監聽的回調方法,通過它來處理加載更多邏輯
不定期分享關于 安卓開發 的干貨,追求 短、平、快 ,但 卻不缺深度 。
選擇一個aar文件,我這里用DynamsoftBarcodeReader.aar。
把目錄flutter/examples/hello_services/android/導入到Android Studio中。
點擊File New New Module,選擇Import .JAR/.AAR Package,添加AAR文件。打開工程屬性,添加依賴模塊就可以了。