Flutter 快速實現(xiàn)聊天會話列表效果示例詳解
一、目標效果
聊天會話頁的列表效果
- 1、聊天數(shù)據(jù)不滿一屏時,頂部顯示所有聊天數(shù)據(jù)
- 2、插入消息時
- 如果最新消息緊靠列表底部時,則插入消息會使列表向上推
- 如果不是緊靠列表底部,則固定到當前聊天位置
效果如圖所示:
二、原理
1、 涉及的方法
ScrollPhysics
提供了 adjustPositionForNewDimensions
方法,用于修正 ScrollView
在 rebuild
后的偏移量,方法聲明如下
double adjustPositionForNewDimensions({ required ScrollMetrics oldPosition, required ScrollMetrics newPosition, required bool isScrolling, required double velocity, })
默認情況下,值為上一次的偏移量,即 newPosition
參數(shù)的 pixels
,所以在頂部插入消息時,消息列表就會跟隨滾動。
如下圖所示,觀察藍色的消息條目,每播入一條消息時,所有消息會自動往上頂,而滾動視圖的偏移量其實一直是沒有變化的~
注:值得注意的是,如果該方法返回的值與 newPosition
的 pixels
不相等時,則會觸發(fā)視圖的重新布局,所以這個操作還是比較昂貴的,應盡量減少返回值的變動。
2、實現(xiàn)邏輯
根據(jù)上述內容我們不難推出插入消息時的效果實現(xiàn)原理如下:
效果 | 返回的值 |
---|---|
消息緊靠列表底部時,插入消息會使列表向上推 | 直接返回 super 的值,即 newPosition 參數(shù)的 pixels |
如果不是緊靠列表底部,則固定到當前聊天位置 | 返回原本第 0 條消息的最新偏移量 |
下面重點說明一下第 2
點中 返回原本第0條消息的最新偏移量 的實現(xiàn)邏輯:
ListView
的本質是 RenderSliverList
,通過 RenderSliverList
的 firstChild
屬性拿到當前列表中渲染的首個 item
。
如下圖,firstChild
是下標為 10
的 item
,這個 item
與預渲染區(qū)域 cacheExtent
相關,如果將其設置為 0
,則 firstChild
的下標將會是 12
,這個相信不難理解。
所以,我們只需要在插入消息時,記錄第 0
條消息的偏移量,當列表視圖 rebuild
后,adjustPositionForNewDimensions
方法會被調用,此時取出第 1
條消息的偏移量,兩者的差值加上 super
的值即為目標修正偏移量。
至于 聊天數(shù)據(jù)不滿一屏時,頂部顯示所有聊天數(shù)據(jù) 這個效果只是在切換 shrinkWrap
而已,比較簡單就不在此展開講了。
我已將上述邏輯進行了封裝,集成于 flutter_scrollview_observer,接下來我們就來看看如何使用。
三、使用
現(xiàn)在只需三個步驟即可快速實現(xiàn)聊天會話列表的效果
步驟一:初始化必要的 ListObserverController
和 ChatScrollObserver
/// 初始化 ListObserverController observerController = ListObserverController(controller: scrollController) ..cacheJumpIndexOffset = false; /// 初始化 ChatScrollObserver chatObserver = ChatScrollObserver(observerController) ..toRebuildScrollViewCallback = () { // 這里可以重建指定的滾動視圖即可 setState(() {}); };
步驟二:按如下配置 ListView
并使用 ListViewObserver
將其包裹
Widget _buildListView() { Widget resultWidget = ListView.builder( physics: ChatObserverClampinScrollPhysics(observer: chatObserver), shrinkWrap: chatObserver.isShrinkWrap, reverse: true, controller: scrollController, ... ); resultWidget = ListViewObserver( controller: observerController, child: resultWidget, ); return resultWidget; }
步驟三:插入或刪除消息前,調用 ChatScrollObserver
的 standby
方法
onPressed: () { chatObserver.standby(); setState(() { chatModels.insert(0, ChatDataHelper.createChatModel()); }); }, ... onRemove: () { chatObserver.standby(isRemove: true); setState(() { chatModels.removeAt(index); }); },
注:示例中的 setState
都可以換成對列表視圖進行局部刷新的代碼
四、最后
GitHub地址: flutter_scrollview_observer
該庫還實現(xiàn)了其它十分實用的功能,相關功能有對應的文章進行敘述
以上就是Flutter 快速實現(xiàn)聊天會話列表效果示例詳解的詳細內容,更多關于Flutter 聊天會話列表的資料請關注腳本之家其它相關文章!
相關文章
Flutter使用AnimationController實現(xiàn)控制動畫
這篇文章主要想帶大家來嘗試一下Flutter如何使用AnimationController實現(xiàn)一個拖拽圖片,然后返回原點的動畫,感興趣的可以了解一下2023-05-05Kotlin中常見內聯(lián)擴展函數(shù)的使用方法教程
在Kotlin中,使用inline修飾符標記內聯(lián)函數(shù),既會影響到函數(shù)本身, 也影響到傳遞給它的Lambda表達式,這兩者都會被內聯(lián)到調用處。下面這篇文章主要給大家介紹了關于Kotlin中常見內聯(lián)擴展函數(shù)的使用方法,需要的朋友可以參考下。2017-12-12