【Flutter】自定义ListView开发记录(五)—— 提供手势等信息

1,098 阅读2分钟

「这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战」。

前言

前面基本完成了实现阅读器所需的修改;现在还差一部分,提供出来当前ListView的index、手势位置等信息,以供item页面使用(仿真翻页);

思路

为了降低侵入性,我计划打算通过 在 ListView 的 Scrollable 外面套一层 PrimaryScrollController ,在其中存放保存数据的 ChangeNotify ;这样由于 Item所在的Widget 均在ListView的 Widget树中,自然可以通过 of方法获取到,并获取到需要的 ChangeNotify 中的数据;

另外用这种方式,知道自己展示内容的SliverList,也可以在特定时机,把一些当前 child拥有的parentData传上去;这些parentData包含了index、scrollOffset 等信息,还是挺有用的;

而且对于Item来说,可以通过诸如 addListener(markNeedsLayout) 这种方式,方便的触发手势响应;

实现

这块的实现其实也很简单,最简陋的实现如下:

image.png

image.png

image.png

然后重写ListView的build方法:

image.png

至于如何去使用这个,就要涉及到另一部分了;

首先,因为只有仿真翻页才会使用到这里提供的手势信息,所以以仿真翻页为例:

(请自觉无视掉其中令人瞎眼的测试页,以及仅仅完成了部分仿真翻页效果,还有莫名其妙的Item位移)

image.png

可以看到,需要对 Item本身进行裁剪,这就要涉及到对canvas进行操作;一提到这个,自然想到的控件就是CustomPaint了;

但是经过研究,我发现CustomPaint仅仅提供了再canvas绘制前和绘制后的操作;

另外如果对canvas擦除清空(我使用的是 canvas.drawColor(Colors.red, BlendMode.clear); 不知道还有没有其他的擦除方式),按照本来的设想,应该是透明页面才对,然而最终效果不是透明,而是黑色……

最后再github issue区发现一种解决方式:

image.png

github.com/flutter/flu…

不过要实现这种效果,就需要自定义CustomPaint了;不过因此也能参考CustomPaint的方式,自动给手势添加markNeedPaint;

最终的粗略版自定义实现部分:

image.png

应该还有不少可以优化的地方,如果能解决那个黑色的问题,或许就可以避免使用saveLayer这种不推荐的实现方式;

结语

自此,对小说阅读器所需的部分,都已经实现出来了;

接下来或许就可以通过自定义的ListView来实现一个小说阅读器;这样不仅能摆脱canvas部分的限制,自由的布局和使用已经提供的widget;而且可以让Item部分拆离开来,更加注重自身实现,而非像canvas实现方式那样,一个canvas绘制了所有部分;