【Flutter】自定義ListView開發記錄(四)—— 關於ParentData的設想和分析與簡單實踐
theme: condensed-night-purple
「這是我參與11月更文挑戰的第11天,活動詳情檢視:2021最後一次更文挑戰」。
前言
前面對hitTest方法進行了修改,以實現點選事件的處理;
但是肯定有人看出來了,這就是個治標不治本的方法,說白了,在整個SliverList流程中傳遞的資料並未修改,對於其他部分而言,它們還是根據資料,認為item按照ListView那種依次排列的方式進行的;
隨著後續自定義ListView功能的增多,這部分肯定會造成困擾和誤導;
那現在就來從資料來源的角度進行一下修改;
評估
首先,先來確認下ParentData中的資料和其作用:
SliverList中parentData是 SliverMultiBoxAdaptorParentData ,在其中存放的是 index 和 keepAlive ;作用嘛,字面意思:
其父類放的就是經常使用的layoutOffset引數:
還有兩個mixin,一個用來存放child連結串列關係:
另一個還是keepAlive相關……至於這個keepAlive和keptAlive有啥區別……好像沒區別,get都給重寫掉了……
現在要關注的是layoutOffset,起初我的想法是修改layoutOffset;但是layoutOffset所提供的作用不僅僅是為了表明位置,通過這個還能得知Item之間的相對位置關係;說白了就是能通過layoutOffset得知當前child前面多少多少是上一個child;
所以像現在這種,從lastChild往前遍歷的方式上,能知道各個child之前的相對位置關係;還是挺有必要的~畢竟firstChild 並不一定會顯示在ViewPort指定的可視範圍內,如果所有child的layoutOffset都是實際在canvas上的位置,那麼如何得知當前ScrollOffset對應哪些child呢;
糾結了一小段時間後,我發現,在原始碼中有這麼個一個變數:paintOffset;比如說這種:
既然原始碼中有這種東西,或許追蹤一下就知道怎麼搞了
有個讓我困惑的地方
首先還是先看註釋:
按照註釋說明,這東西正是我所需要的東西,用來體現child相對於parent位置的;
不過有個讓我有點疑惑的東西,在註釋中明確說明這東西最好用在僅有少量child的view上面;為啥這麼說呢,講道理設定個paintOffset,和設定layoutOffset沒太大區別吧,無非到時候根據scrollOffset計算一下而已;
檢視一下呼叫位置,確實正如註釋中說明的那樣,基本都是隻持有一個child的那種View在使用這個parentData;
其具體呼叫位置也是performLayout這塊;例如這樣:
其中一個呼叫位置是這樣的:
好像沒啥太複雜的計算,或者延時操作啊,為啥指定持有少量child的View呢?
設計
我設想的方案同樣是在performLayout 這塊,在計算了各個item的 layoutOffset的同時, 結合情況,將paintOffset也計算出來,以目前計劃實現的覆蓋翻頁為例:
那麼需要做的事就明確了:
- 提供設定一個新的ParentData,用於儲存paintOffset;
- 提供一個計算paintOffset的方法,提供給LayoutOffset;
- 修改paint方法,改為根據paintOffset來繪製;
- 修改hitTest方法,同樣改為根據paintOffset來計算;
參考原始碼,ctrl + CV戰士無所畏懼;
結尾
目前簡單測試了下,並未發現什麼效能損耗;所以註釋中那段確實讓我挺困惑的
- 【Flutter】小說閱讀器改版 —— 翻頁動畫(三)
- 【Flutter】小說閱讀器改版 (六)—— 在動畫播放中攔截手勢
- 【Flutter】小說閱讀器改版 (五)—— 整合ScrollActivity
- 【Flutter】小說閱讀器改版 (四)—— 讓ScrollActivity追蹤手勢最新位置
- 【Flutter】小說閱讀器改版 (三)—— 實現支援 Drag 的ScrollActivity
- 【Flutter】小說閱讀器改版 (二)—— 改進一下模擬翻頁的效果
- 【Flutter】小說閱讀器改版 (一)—— 模擬翻頁的思路優化
- 【Flutter】自定義ListView開發記錄(五)—— 提供手勢等資訊
- 【Flutter】自定義ListView開發記錄(四)—— 關於ParentData的設想和分析與簡單實踐
- 【Flutter】自定義ListView開發記錄(三)—— 處理HitTest手勢事件
- 【Flutter】自定義ListView開發記錄(二)——設計LayoutManager
- 【Flutter】自定義ListView開發記錄(一)——設計滑動效果的處理方式
- 【Flutter】熊孩子拆元件系列之拆ListView(十)—— 按自己的方式組裝修改ListView
- 【Flutter】熊孩子拆元件系列之拆ListView(九)—— AutomaticKeepAlive和KeepAlive
- 【Flutter】熊孩子拆元件系列之拆ListView(八)—— SliverList的運作機制
- 【Flutter】熊孩子拆元件系列之拆ListView(七)—— SliverList的基礎結構
- 【Flutter】熊孩子拆元件系列之拆ListView(六)—— SliverPadding
- 【Flutter】熊孩子拆元件系列之拆ListView(五)—— ViewPort
- 【Flutter】熊孩子拆元件系列之拆ListView(四)—— _ScrollableScope
- 【Flutter】熊孩子拆元件系列之拆ListView(三)—— GlowingOverscrollIndicator