[Flutter]从零开始实现一个嵌套滑动的PageView(二)

3,554

目录

  1. [Flutter]从零开始实现一个嵌套滑动的PageView(一)
  2. [Flutter]从零开始实现一个嵌套滑动的PageView(二)
  3. [Flutter]从零开始实现一个嵌套滑动的PageView(三)

前言

前面实现了嵌套滑动,那么下面,就要考虑如何将动画加入其中

首先需要了解的知识(课前准备)

  1. Flutter中管理动画的部分其实就是physics,但是physics的动画效果是如何设置并应用给pageView,并供其展示的呢?这时候需要了解的部分就是ScrolActivity。
  2. Flutter中触摸事件分为dragStrat、dragDown等等,但是我们在NestedScrollerView中并没看到相关的触摸事件,其实flutter已经对触摸事件进行了基本处理,并将触摸事件转换为效果,这时候需要我们了解的部分就是drag,hold以及goIdel,goBallistic 等方法。

将所有事件统一交给一个管理器管理分发

在NestedScrollerView 中 嵌套滑动的处理是由_NestedScrollCoordinator 统一管理处理的,为了能够协调当前body和header,这应该是最直接的方式

所以按照NestedScrollerView 中_NestedScrollCoordinator 的做法,创建一个类,继承ScrollActivityDelegate和ScrollHoldController,并修改position 的方法,将其中drag,hold等需要协调处理的方法交由这个新类实现。

跟NestedScrollerView不同的是,嵌套滑动判断优先级应以最先接收到事件的控件先做响应,比如说,如果我先收到的是子Page的滑动事件,在无法滑动或者事件处理完之前,外部的pageView都应该是无法响应的。而非NestedScrollerView中根据滑动方向判断优先级的方式。

所以为了实现上面一点,我们可以给position加上是不是inner这个标志,然后根据drag方法传入的inner标志判断当前触发的position是子Page还是父Page。

在overScroll的时候,将子PageView的事件转给父Page

在applyUserOffset 方法中,判断子Page的position,其pixels加上滑动距离是否大于maxScrollExtent,通过这个简单判断一下是不是overScroll,并将事件根据结果分发给子Page或者父page

在goBallistic 方法中,我是根据滑动方向判断子Page是否会overScroll。

当然,别忘了加上inner标志的处理

Look Look 效果

NestedPageView
NestedPageView

后记

现在解决掉了嵌套动画的问题,说白了就是处理goBallistic以及Activity;
那么下面还需解决的问题还有:

  1. 连续快速滑动(非常快速滑动的情况下,子Page偶尔会出现未滑动到底) (额,这是个低级bug……已解决)
  2. 2020.3.11新鲜出炉的bug:如果有两个在View树中同级的PageView(举个例子:演示图中如果红色详情页中再放一个PageView,那么这个新增加的PageView就跟带BottomNavigationbar的那个页面中的PageView是同级的,都是主PageView的子布局)存在,则会出现position争抢绑定的ScrollerConttroller的问题……(解决思路也比较简单,以前是在最顶部的父pageView进行计算,并控制子PageView的,当时思路参考自NestedScrollerView……但是如果由子PageView自己来计算,然后通过PrimaryScrollerController获取到父PageView的控制器不就完事了……一个View可能有多个子View,但是一定只有一个父View…… PS:好像这样弄一下可以整合出一个套娃功能来,下篇文章补充一下整体设计)