【Flutter】小说阅读器改版 (三)—— 实现支持 Drag 的ScrollActivity

「这是我参与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的限制,固定一个时间和距离、速度,最后不断判断是否到达规定终点,提前结束这种计算方式?

猜你喜欢

转载自juejin.im/post/7033745858457763848