Flutter 更换overscroll过度滚动效果

401 阅读1分钟

在 Flutter 中,overscroll 效果通常指的是当用户尝试滚动超出滚动视图的边界时所产生的效果。这种效果在 Android 和 iOS 上有所不同,Flutter 会自动选择对应平台的效果

在 Android 12 之前,当用户尝试滚动超出边界时,会看到一种被称为 glow 的效果,这是一种发光效果。然而,在 Android 12 中,这种效果被改变为了一种被称为 stretch 的效果,这是一种拉伸效果

在 ThemeData 中有一个 androidOverscrollIndicator 属性可以来指定希望使用哪种 overscroll 效果,但在 Flutter 的 v2.13.0-0.0.pre 版本后已被弃用。取而代之的是,你可以使用 ThemeData.useMaterial3 或者重写ScrollBehavior.buildOverscrollIndicator

OverscrollIndicator 本质上就是一个组合型 Widget ,有兴趣的可以去看看源码,Flutter 已经定义了好几种Indicator

StretchingOverscrollIndicator为例,对一个 ListView 作用时直接包含子 Widget

StretchingOverscrollIndicator(
  axisDirection: AxisDirection.down,
  child: ListView.builder(
    itemCount: 12,
    itemBuilder: (context, index) {
      return ListTile(
        title: Text("item $index"),
      );
    },
  )
)

这样这个 ListView 的滚动效果就变成了 stretch

要在整个应用中为所有的 ListView 使用 StretchingOverscrollIndicator,可以通过创建一个自定义的 ScrollBehavior 来实现,在这个自定义的 ScrollBehavior 中,你可以重写 buildOverscrollIndicator 方法来返回一个 StretchingOverscrollIndicator ,然后,你可以在你的应用的最顶层使用这个自定义的 ScrollBehavior

class MyScrollBehavior extends ScrollBehavior {
  @override
  Widget buildOverscrollIndicator(BuildContext context, Widget child, ScrollableDetails details) {
    return StretchingOverscrollIndicator(
      axisDirection: details.direction,
      child: child,
    );
  }
}
void main() {
  runApp(MaterialApp(
    home: HomePage(),
    builder: (context, child) {
      return ScrollConfiguration(
        behavior: MyScrollBehavior(),
        child: child!,
      );
    },
  ));
}

这样 App 就从默认的 grow 效果换成了 stretch 效果,因为 Android 12 以后变成了 stretch 效果,根据系统版本更换可以让 App 有更好的一致性