【Flutter】小說閱讀器改版 (二)—— 改進一下模擬翻頁的效果
theme: condensed-night-purple
「這是我參與11月更文挑戰的第14天,活動詳情檢視:2021最後一次更文挑戰」。
前言
現在所需的ListView改造好了,可以去將ListView應用到小說閱讀器上;但是按照之前的實現,現在還需要實現一些準備部分;
要實現的效果:
首先,在之前的文中,僅僅實現了覆蓋翻頁的LayoutManager,模擬翻頁也需要一個,不過這次挑戰一下更模擬的模擬翻頁(參考小米閱讀App的模擬翻頁效果)
在之前專案中,前一頁的翻頁效果跟後一頁是一樣的,除了方向並無區別;
而在小米閱讀上,效果是從前往後翻到指定位置:
分析
要實現這種效果,我想有兩種思路:
-
第一種:固定載入兩頁,當觸發手勢操作的時候,第一頁固定展示最頂層的效果;而不是固定展示最頂層的那頁(舉個例子,如果有1,2,3三頁,當前處於第二頁,往前翻的時候,第一頁展示的是第一頁,第二頁處於底部,展示第二頁的部分;但往後翻的時候,第一頁展示的是當前所看的第二頁的效果,第二頁展示第三頁的部分)
-
第二種:固定內容跟Item繫結,結合ScrollController和其所持有的position,計算各種操作應該變化多少offset,再通過之前提供出來的手勢資訊,讓各個Item自己判斷是否要展示翻頁效果;(這種情況下舉例的話,應該是動態載入的兩頁,這兩頁繫結所展示的內容,還是之前的那個例子,往前翻,ListView先改變offset到特定位置,然後第一頁展示翻頁效果,第二頁展示第二頁;往後翻,第二頁展示第二頁的翻頁效果,第三頁就展示第三頁;)
第一種思路,就是之前通過canvas來實現的效果;優點就是省事,缺點嘛,也很明顯,各種頁面切換,不好上手理解;
第二種思路,就是我現在想實現的方式,優點就是讓Item只通過資料驅動,沒有什麼狀態切換之類的東西;缺點就是會複雜不少,畢竟要通過資料來驅動;而非直接修改;
實現:
以手勢操作開始分析:
- 因為僅僅是移動的時候生效,所以很明顯是move事件觸發的,那麼如果我 move 事件觸發的時候,將Item移動到指標所在的位置,然後Item繪製翻頁效果的時候,指標的橫向座標使用offset偏移量,縱向還是用指標的縱座標,這種方式是否可以呢?
將Item移動到指定位置,可以通過ScrollController的 animateTo 方式來實現;
之前的分析中也說明了,可以通過 Controller 來獲取 position ,裡面儲存了包括偏移量,Item寬度等資訊,這樣也可以計算出要移動到的位置;
看上去好像沒什麼問題?
做個小型demo實驗一下,為了方便看出效果,以覆蓋翻頁的layoutManager為例,並僅僅計算處理一次move事件簡單驗證下:
確實是可以在move事件中呼叫animateTo方法改變offset;但是也發現一個問題,後續的拖動事件全部失效~
原因嘛,是因為animateTo方法會呼叫beginActivity,這個新的activity是 DrivenScrollActivity ,因為呼叫了新的activity,drag的activity會被中斷銷燬:
但是drag僅僅在dragStart的時候建立,所以後續的move事件呼叫不到drag來處理,自然沒有效果~~~
結尾
看來要想以第二種方式來實現小米閱讀的效果;也沒那麼輕鬆,接下來的想法是對 ScrollActivity 進行處理;如果在現在的效果上,能不中斷drag,自然所有問題就能解決,接下來我會先嚐試以下兩個方法:
- 自定義ScrollActivity,接管drag和那個負責animatedTo的DrivenScrollActivity?這樣他倆都是一個東西,自然不會衝突銷燬;
- 對beginActivity進行修改,讓其在特定條件下不去銷燬drag;通過優先順序來對任務排程;
- 自己看看能否實現一個新的animatedTo方法,通過不斷模擬drag事件的方式來觸發;
- 【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