【Flutter】自定義ListView開發記錄(五)—— 提供手勢等資訊
theme: condensed-night-purple
「這是我參與11月更文挑戰的第12天,活動詳情檢視:2021最後一次更文挑戰」。
前言
前面基本完成了實現閱讀器所需的修改;現在還差一部分,提供出來當前ListView的index、手勢位置等資訊,以供item頁面使用(模擬翻頁);
思路
為了降低侵入性,我計劃打算通過 在 ListView 的 Scrollable 外面套一層 PrimaryScrollController ,在其中存放儲存資料的 ChangeNotify ;這樣由於 Item所在的Widget 均在ListView的 Widget樹中,自然可以通過 of方法獲取到,並獲取到需要的 ChangeNotify 中的資料;
另外用這種方式,知道自己展示內容的SliverList,也可以在特定時機,把一些當前 child擁有的parentData傳上去;這些parentData包含了index、scrollOffset 等資訊,還是挺有用的;
而且對於Item來說,可以通過諸如 addListener(markNeedsLayout) 這種方式,方便的觸發手勢響應;
實現
這塊的實現其實也很簡單,最簡陋的實現如下:
然後重寫ListView的build方法:
至於如何去使用這個,就要涉及到另一部分了;
首先,因為只有模擬翻頁才會使用到這裡提供的手勢資訊,所以以模擬翻頁為例:
(請自覺無視掉其中令人瞎眼的測試頁,以及僅僅完成了部分模擬翻頁效果,還有莫名其妙的Item位移)
可以看到,需要對 Item本身進行裁剪,這就要涉及到對canvas進行操作;一提到這個,自然想到的控制元件就是CustomPaint了;
但是經過研究,我發現CustomPaint僅僅提供了再canvas繪製前和繪製後的操作;
另外如果對canvas擦除清空(我使用的是 canvas.drawColor(Colors.red, BlendMode.clear); 不知道還有沒有其他的擦除方式),按照本來的設想,應該是透明頁面才對,然而最終效果不是透明,而是黑色……
最後再github issue區發現一種解決方式:
http://github.com/flutter/flutter/issues/24466#issuecomment-439611100
不過要實現這種效果,就需要自定義CustomPaint了;不過因此也能參考CustomPaint的方式,自動給手勢新增markNeedPaint;
最終的粗略版自定義實現部分:
應該還有不少可以優化的地方,如果能解決那個黑色的問題,或許就可以避免使用saveLayer這種不推薦的實現方式;
結語
自此,對小說閱讀器所需的部分,都已經實現出來了;
接下來或許就可以通過自定義的ListView來實現一個小說閱讀器;這樣不僅能擺脫canvas部分的限制,自由的佈局和使用已經提供的widget;而且可以讓Item部分拆離開來,更加註重自身實現,而非像canvas實現方式那樣,一個canvas繪製了所有部分;
- 【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