【Flutter】熊孩子拆组件系列之拆ListView(四)—— _ScrollableScope

1,570 阅读2分钟

小知识,大挑战!本文正在参与「程序员必备小知识」创作活动

本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。

前言

按照顺序,上次分析了 GlowingOverscrollIndicator ,虽然那东西难度不大,不过作为组合型Widget,其本身在Widget树中占了不少;

所以去掉相关的部分,接下来分析的是:_ScrollableScope

目录

juejin.cn/post/701653…

同样的惯例,先看注释,概念分析

不过呢,这回注释就短短两行:

// Enable Scrollable.of() to work as if ScrollableState was an inherited widget.
// ScrollableState.build() always rebuilds its _ScrollableScope.

不过确实,_ScrollableScope 本身并不复杂,也就十来行代码,一看就能看懂,说白了,作为一个InheritedWidget ,其所做的事也就一件:存储共享数据;

在这里,其所共享的数据是ScrollableStateScrollPosition;那么问题来了,存储共享这俩图个啥呢?

共享的数据都用来干了啥

1、首先是ScrollableState ;可以看到,其本身被提供使用的地方只有一处:

static ScrollableState? of(BuildContext context) {
  final _ScrollableScope? widget = context.dependOnInheritedWidgetOfExactType<_ScrollableScope>();
  return widget?.scrollable;
}

结合其调用位置,使用这个方法的用处无非两种类型:

  1. 使用state中的数据,甚至是state本身,来进行一些判断操作;
  2. 使用state中的position和physics来进行一些手势动作计算,并更新position中的信息;

2、另一个共享的数据有点意思:同样还是 position;

那么问题又来了:

为啥要单独提供一个position出来,直接使用上面的ScrollableState中的position不就行了?或者说,这个position跟上面用state获取的position难道有什么不同么?

这个问题我还没想出答案,我猜测:该不会就是为了方便调用?讲道理,_ScrollableScope 跟随 ScrollableState 的生命周期,重建的时候也一起重建,postion 应该跟 state中的永远保持一致才是,不至于有区别吧;

回正题,这个position 的作用是?

还记得之前提到的一个有点意思,用于延迟加载的判断方法不,这个position就用在这里:

static bool recommendDeferredLoadingForContext(BuildContext context) {
  final _ScrollableScope? widget = context.getElementForInheritedWidgetOfExactType<_ScrollableScope>()?.widget as _ScrollableScope?;
  if (widget == null) {
    return false;
  }
  return widget.position.recommendDeferredLoading(context);
}

关于_ScrollableScope 本身的分析也就到这了;应该说,类型是InheritedWidget都应该不会太复杂,本身也就提供共享数据而已;

重点是使用这些共享数据的;