【Flutter】小說閱讀器改版 (三)—— 實現支援 Drag 的ScrollActivity

語言: CN / TW / HK

theme: condensed-night-purple

「這是我參與11月更文挑戰的第15天,活動詳情檢視:2021最後一次更文挑戰」。

前言

之前一篇文章中,遇到了一個問題:

由於controller的animateTo事件會觸發ScrollPosition呼叫beginActivity(DrivenScrollActivity()),進而中斷掉drag事件;

想了一下,決定用自定義ScrollActivity的方式來處理這個問題;

先看下原始碼中的實現方式:

在ListView中,animateTo方法所做的事很簡單:

image.png

說白了就是呼叫position去處理;

而position所做的事,是將任務交給scrollActivity處理:

image.png

而這個scrollActivity,也不復雜,說白了就是通過 AnimationController 計算,並不斷將結果setPixels;最後呼叫一下 goBallistic、goIdle來複位;

image.png

好像沒啥複雜的東西…………寫個新的也不難搞;

實現方式

實現方式這塊,好像要改動的東西也不多:

  • 對新的ScrollActivity而言,相容drag所做的事也不復雜:判斷一下 delegate ,也就是ScrollPosition, 看下它持有的currentDrag是否為空,如果為空的話,跟現在的DrivenScrollActivity一模一樣;不為空的話,所做的事就是在結束的時候不呼叫goIdle或者goBallistic復位壞事;

  • 動畫這塊,對beginActivity 進行下修改,判斷一下是否需要清除Drag;

根據以上的思路,我新建了一個ScrollController和ScrollPosition;以及一個新的ScrollActivity基類。用於儲存是否需要中斷drag的判斷;

ScrollControllerimage.png

ScrollPositionimage.png ScrollPosition這塊,因為好多東西都是私有的……只能完全複製ScrollPositionWithSingleContext這個,然後自己根據需要修改;

image.png

ScrollActivity

image.png image.png

結尾

簡單修改了下,好像效果還可以?

QQ20211123-202944-HD.gif

不過好像偏移量多計算了一個viewPort,這個是小問題~

不過有個大問題,按照小米閱讀上的效果,即使移動動畫沒結束前就移動手指,最終也能很流暢的跟蹤到最終手指停留的位置;而現在,如果在動畫未結束前一直移動手指,動畫會一直不會開始~

至於原因,也很簡單,每次滑動手指,都會觸發animateTo方法,而一直滑動就會一直觸發,AnimationController 也會一直銷燬重建,無法真正執行起來;

看來接下來要對 AnimationController 的計算方式做些修改?或許應該脫離現在這種from和to的限制,固定一個時間和距離、速度,最後不斷判斷是否到達規定終點,提前結束這種計算方式?

「其他文章」