江枫

LoopScrollRect滚动条扩展

    最近在研究滚动条的制作,主要研究的是两个github上的开源项目:LoopScrollRect基于动画的滚动条FancyScrollView
    但是因为基于动画的滚动条复用性不高,每次制作一个新的滚动条都需要重新构建动画,而且看demo中整体的滚动布局不是很清晰,最终选择LoopScrollRect作为开发的基准,但是LoopScrollRect中的功能支持的不完全,还需要自己再进行一些开发工作。

1.滚动到末尾时的Content位置错误问题

    Demo中提供了两个滚动到指定下标的接口:SrollToCellSrollToCellWithinTime,分别表示以指定的速度或指定的时间滚动到对应格子。在对应的滚动条组件上也有对应接口调用的按钮:

    但当滚动到最后一个格子且速度或时间小于0时,组件内部其实调用的就不再是滚动接口,而是ReFillCells接口,但是这个接口不是从后向前重新ReFill,而是从前向后,所以有的时候调用该接口就会发现想跳转到最后一个格子,但是ReFill之后根本看不到最后一个格子。

    如果想解决这个问题,也许可以通过一些条件判断配合RefillCellsFromEnd(从后向前重新填充格子)接口进行处理。

2.滚动到指定格子时该格子始终在列表最上方或最左方

    举个栗子,比如我们现在要SrollToCell(14, 1f),滚动之后的结果就会变成这样:

    目标格子会被滚动到最上方,但是如果我们想要目标滚到中间或者是滚到最下方应该怎么办呢?在格子滚动的实际逻辑中,在计算偏移量时使用的是ViewBounds和格子的Bounds的上边界差进行计算,所以最终格子会被移动到最上方:

3.滚动结束时滚回到当前选择的页签

GIF

    想做一个和FancyScroll类似的卡在某个格子的功能,但是LoopScrollRect并没有提供对应的功能。看了一下FancyScroll其实是在update滚动计算位置时,当速度小于某个阈值时就直接滚动到指定下标或者指定位置。

    于是我们也可以照虎画猫整一个类似的东西,但是在看LoopScrollRectBase代码时发现,这里的代码update和那边基本一样:

4.滚动停止功能导致锁定失效

    由于LoopScrollRectBase继承了IInitializePotentialDragHandler接口,实现了对应的OnInitializePotentialDrag函数,该函数接收开始拖动的点击事件,并在该回调函数中将滚动速度置为0,所以导致上述的锁定逻辑无法执行。然后就会出现滚动条没有被锁住而是卡在了中间的诡异情况。
    在FancyScroll中没有实现IInitializePotentialDragHandler接口而是实现IPointerDownHandlerIPointerUpHandler接口实现相同功能,可是我在LoopScrollRectBase中使用这两个接口时无法生效。暂时不知道是什么原因。
    暂时没想到什么好的处理方案,于是只是简单的在OnInitializePotentialDrag接口内调用了一次锁定滚动条的操作。

GIF

文章大纲