flutter源码系列 PageView源码分析以及监听事件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了flutter源码系列 PageView源码分析以及监听事件相关的知识,希望对你有一定的参考价值。

参考技术A 最近一个项目要实现可以无限循环的PageView,主要思路是在初始化pageview的list的时候在开始和结尾多加一个结尾和开头的widget,当滑动到开头和结尾的时候手动进行页面的切换,详细可以搜索pageview无限轮播。
这种方法有一个要点就是要维护两个索引,一个是内部list的索引,一个是外部显示的索引,由于list的容量是比显示的数量多2的,所以如果要在外部进行一些比如指示器或者计时器功能要进行和页面同步显示或者切换页面操作时,需要将显示的索引转换成list的索引。
不过网上说的都是一些比较简单的实现,看到比较多的就是当滑动到要手动切换的时候进行一个时延,这样可以避免直接切换页面造成的卡顿和跳动现象。但是存在一个问题,如果要同时实现一个跟随页面切换的指示器,就会出现当页面切换过去之后指示器才会跟着过去,因为页面切换的时候执行了时延,而时延之后才会真正改变索引,此时才会setstate,之后指示器才能响应到索引的切换,但是如果在时延之前就切换的话又会出现指示器先行的情况。因此这种方法其实是存在一些问题的。
所以解决这个问题的关键在于如何进行页面切换的判断。这里可以有两种思路实现,第一种是实现viewpage的onpagechanged方法,在里面进行逻辑的判断,然后用controller来进行页面跳转,不过这种方法存在当controller跳转的时候又会回调onpagechanged,所以就会出现多次对索引不必要操作,而且如果有比如计时器等额外的功能的话可能不方便将页面逻辑分开,而且依旧无法解决指示器延迟问题,同时也很难进行细粒度的操作。
第二种方法我们就要去看pageview的源码了,从源码的角度来解决问题才是正确的方法。首先我们点进去pageview的源码

看到这里其实已经有一些思路了,我们之前难点在于重写了onpagechanged方法导致问题无法很好的解决,现在我们找到了onpagechanged调用的地方,只要找办法避免掉就可以实现了。
当然这里我们要说到NotificationListener,以及flutter对应的冒泡事件传输机制,这里大家可以去看看这篇 文章 。
我来总结一下,其实就是flutter对于notification这个组件,有一中事件规则叫冒泡传递,底层的notification如果在它的 onNotification写的逻辑中返回是false以及它不是根结点,就会去向上遍历寻找它的祖先notification组件,知道遇到root节点或者某一个返回true,则事件传递结束。
而且在onNotification中可以对多种事件进行监听和处理,所以我们可以把对viewpage页面跳转对索引处理的逻辑写在这里,而且我们可以分别处理比如滑动开始的start事件和结束的end事件,分别进行细粒度的逻辑的处理,这样就可以在外部进行操作和别的功能实现了。

因此不仅无限轮播事件可以通过这种方法来解决,如果有其他的操作也可以这样进行处理,而且因为我们没有传入onpagechanged方法,所以不存在多次调用的问题,pageview那里判断onpagechanged是null方法就不会进去了,会直接我们写在pageview外面的notification的逻辑。
最后的结构大概这样

以上是关于flutter源码系列 PageView源码分析以及监听事件的主要内容,如果未能解决你的问题,请参考以下文章

Flutter Dio源码分析--封装

Flutter Dio源码分析--Dio介绍

Flutter Dio源码分析--深度剖析

flutter框架(源码分析)

Flutter Dio源码分析--HttpClientHttpDio对比

Flutter 命令本质之 Flutter tools 机制源码深入分析