【Flutter】小說閱讀器改版 (五)—— 整合ScrollActivity

語言: CN / TW / HK

theme: condensed-night-purple

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

前言

在前一篇文章中,通過自定義ScrollActivity的方式基本實現了需求,但是由於沒有處理DragActivity,所以DragActivity和自定義的心ScrollActivity在手勢方面處於衝突狀態;

雖說僅僅從UI表現層面來說好像沒什麼太大問題,但是畢竟是個問題;

設計

既然現在存在的問題是跟darg 有衝突,那麼我將所有的處理都搬到Drag裡面去處理不就行了,

回顧一下,需要做的事也不多,: - 建立AnimationController; - 在合適時機去啟動、停止; - 根據情況將事件分別交給Drag和AnimationController去處理;

而在 ScrollDragController 中,涉及對事件處理的部分也就三個:update、end、cancel;

update方法的入參 DragUpdateDetails 中,就有手勢位置資訊,這樣,所需的手勢位置也得知了,啟動動畫自然也不是問題,將方法分發放在這裡就行;

而另外兩個方法:end 和 cancel、以及dispose中,也別忘了加上動畫的取消;

實現

  • 首先來到update方法:

由於所需要處理的手勢,只有從左往右滑動,調出上一頁的事件,所以如果是從右往左滑動,直接super處理即可;

動畫也僅僅需要啟動一次,執行完成後,停留位置肯定是手勢所在的位置,剩下的都交給super處理即可;

同時記得更新一下目標位置,這樣,所需的功能就基本實現了:

按照這個思路,簡單實現一下:

image.png

image.png

對於AnimationController這塊,有個小優化點:在計算AnimateTo方法的目標值的時候,可以根據當前位置和目標位置算出方向,進而修改傳給animateTo的目標值,這樣,無論當前位置是否在手勢位置前後,都可以正常展示動畫到手勢的位置;

image.png 當然,tick 方法中對於邊界的判斷,也跟上面同理,根據方向判斷;

image.png

而 calTargetDx 計算當前目標值的時候,需要注意一下,如果當前page值為整數,需要將page值減1,好將目標指向上一頁上面;

  • cancel 、end 、 dispose 方法

image.png

所做的事也就是終止動畫,停止呼叫而已:

  • 其他部分

image.png

image.png

image.png

由於動畫的存在,使得即使drag事件併為執行呼叫,也有可能更新position資訊;

所以在這裡加一些攔截判斷,讓動畫執行過程中,不再發送通知資訊(或許應該將事件轉換為對應通知的detail資訊?比如說DragUpdateDetails這種)

結尾

現在對手勢進行了區分,再設定上 PageScrollPhysics(),看下效果:

修改後.gif

還剩最後一小點:

在小米閱讀上面,鬆開手指後,在恢復動畫結束前,手勢是不會接受或生效的;

而現在,即使動畫沒結束,手勢操作還是會生效,中斷掉恢復動畫;那再實現下這個效果,基本就沒有任何問題了

「其他文章」