04 ScrollConfiguration 和 ScrollBehavior-2
那么 ScrollBehavior 是这么工作的?
查看 ScrollBehavior 的源码可知,它的 getScrollPhysics 方法中,默认实现了平台返回了不同的 ScrollPhysics ,所以默认情况下,在不同平台上的滚动和边缘推拽,会出现不一样的效果:
ScrollPhysics getScrollPhysics(BuildContext context) {
switch (getPlatform(context)) {
case TargetPlatform.iOS:
return const BouncingScrollPhysics();
case TargetPlatform.android:
case TargetPlatform.fuchsia:
return const ClampingScrollPhysics();
}
return null;
}前面说过, ScrollPhysics 是确定可滚动控件的物理特性 ,那么如上图所示,Android 平台上拖拽溢出的蓝色半圆的怎么来的?ScrollConfiguration 的 ScrollBehavior 是在什么时候被设置的?
查看 ScrollConfiguration 的源码我们得知, ScrollConfiguration 和 Theme、Localizations 等一样是 InheritedWidget,那么它应该是从上层往下共享的。
所以查看 MaterialApp 的源码,得到如下代码,可以看到 ScrollConfiguration是在 MaterialApp 内默认嵌套的,并且通过 _MaterialScrollBehavior 设置了 ScrollBehavior, 其 override 的buildViewportChrome方法,就是实现了Android 上溢出拖拽的半圆效果, 其中 GlowingOverscrollIndicator 就是半圆效果的绘制控件。
@override
Widget build(BuildContext context) {
····
return ScrollConfiguration(
behavior: _MaterialScrollBehavior(),
child: result,
);
}
class _MaterialScrollBehavior extends ScrollBehavior {
@override
TargetPlatform getPlatform(BuildContext context) {
return Theme.of(context).platform;
}
@override
Widget buildViewportChrome(BuildContext context, Widget child, AxisDirection axisDirection) {
switch (getPlatform(context)) {
case TargetPlatform.iOS:
return child;
case TargetPlatform.android:
case TargetPlatform.fuchsia:
return GlowingOverscrollIndicator(
child: child,
axisDirection: axisDirection,
color: Theme.of(context).accentColor,
);
}
return null;
}
}到这里我们就知道了,在默认情况下可滑动控件的 ScrollPhysics 是如何配置的:
- 1、
ScrollConfiguration是一个InheritedWidget。 - 2、
MaterialApp内部利用ScrollConfiguration并共享了一个ScrollBehavior的子类_MaterialScrollBehavior。 - 3、
ScrollBehavior默认根据平台返回了特定的BouncingScrollPhysics和ClampingScrollPhysics效果。 - 4、
_MaterialScrollBehavior中针对 Android 平台实现了buildViewportChrome的蓝色半球拖拽溢出效果。
ps :我们可以通过实现自己的
ScrollBehavior, 实现自定义的拖拽溢出效果。
学员评价