Flutter.源码分析 flutter/packages/flutter/lib/src/widgets/scroll_view.dart/BoxScroll

Flutter.源码分析 BoxScrollView flutter/packages/flutter/lib/src/widgets/scroll_view.dart/BoxScrollView


李俊才 的个人博客blog.csdn.net/qq_28550263

本文地址blog.csdn.net/qq_28550263...

本文提供 Flutter 框架中 BoxScrollView 类源码注释的中文翻译以及必要的分析解说。


目 录


1. 类注释部分

scala 复制代码
/// 使用单一子布局模型的 [ScrollView]。
///
/// {@template flutter.widgets.BoxScroll.scrollBehaviour}
/// [ScrollView] 通常会装饰有 [Scrollbar] 和过度滚动指示器,
/// 这些都由继承的 [ScrollBehavior] 管理。在 ScrollView 上方放置一个
/// [ScrollConfiguration] 可以修改该 ScrollView 的这些行为,
/// 或者可以通过向 [MaterialApp.scrollBehavior] 或 [CupertinoApp.scrollBehavior]
/// 提供 ScrollBehavior 来在应用范围内管理这些行为。
/// {@endtemplate}
///
/// 另请参阅:
///
///  * [ListView],这是一个使用线性布局模型的 [BoxScrollView]。
///  * [GridView],这是一个使用二维布局模型的 [BoxScrollView]。
///  * [CustomScrollView],它可以将多个子布局模型组合成一个单一的滚动视图。
abstract class BoxScrollView extends ScrollView {
  // ...
}

2. 构造方法部分

kotlin 复制代码
/// 创建一个使用单一子布局模型的 [ScrollView]。
///
/// 如果 [primary] 参数为 true,则 [controller] 必须为 null。
const BoxScrollView({
  super.key, // 用于控制是否应替换现有的同类型的 widget
  super.scrollDirection, // 滚动方向
  super.reverse, // 是否反转滚动方向
  super.controller, // 控制滚动位置的对象
  super.primary, // 是否使用主滚动控制器
  super.physics, // 如何应对用户停止拖动后的滚动
  super.shrinkWrap, // 是否根据子项的总长度来设置滚动视图的长度
  this.padding, // 插入子项的空间量
  super.cacheExtent, // 预缓存超出滚动视图的区域的长度
  super.semanticChildCount, // 用于语义通知的子项数量
  super.dragStartBehavior, // 拖动开始行为
  super.keyboardDismissBehavior, // 键盘消失行为
  super.restorationId, // 用于保存滚动位置的 ID
  super.clipBehavior, // 内容超出滚动视图的可视区域时的剪裁行为
});

3. padding属性

arduino 复制代码
/// 插入子项的空间量。
final EdgeInsetsGeometry? padding;

4. buildSlivers方法部分

ini 复制代码
@override
List<Widget> buildSlivers(BuildContext context) {
  Widget sliver = buildChildLayout(context);
  EdgeInsetsGeometry? effectivePadding = padding;
  if (padding == null) {
    final MediaQueryData? mediaQuery = MediaQuery.maybeOf(context);
    if (mediaQuery != null) {
      // 使用 MediaQuery 的 padding 自动填充 sliver。
      final EdgeInsets mediaQueryHorizontalPadding =
          mediaQuery.padding.copyWith(top: 0.0, bottom: 0.0);
      final EdgeInsets mediaQueryVerticalPadding =
          mediaQuery.padding.copyWith(left: 0.0, right: 0.0);
      // 使用 SliverPadding 消耗主轴 padding。
      effectivePadding = scrollDirection == Axis.vertical
          ? mediaQueryVerticalPadding
          : mediaQueryHorizontalPadding;
      // 留下交叉轴 padding。
      sliver = MediaQuery(
        data: mediaQuery.copyWith(
          padding: scrollDirection == Axis.vertical
              ? mediaQueryHorizontalPadding
              : mediaQueryVerticalPadding,
        ),
        child: sliver,
      );
    }
  }

  if (effectivePadding != null) {
    sliver = SliverPadding(padding: effectivePadding, sliver: sliver);
  }
  return <Widget>[ sliver ];
}

可以看出 buildSlivers 方法主要负责构建滚动视图的子组件,并处理可能存在的 padding。

  1. 首先,它调用 buildChildLayout(context) 方法来构建滚动视图的子组件,这个方法在 BoxScrollView 的子类中实现,例如 ListViewGridView
  2. 然后,它检查是否已经设置了 padding。如果没有设置 padding,它会尝试从 MediaQuery 获取 padding。如果 MediaQuery 存在,它会根据滚动方向分别获取垂直和水平的 padding。
  3. 如果 MediaQuery 存在,它会创建一个新的 MediaQuery 组件,将 MediaQuery 的 padding 设置为根据滚动方向得到的 padding,并将原始的子组件作为新的 MediaQuery 组件的子组件。
  4. 如果 effectivePadding(可能是从 MediaQuery 获取的 padding 或者是直接设置的 padding)存在,它会创建一个 SliverPadding 组件,将 effectivePadding 设置为 SliverPadding 的 padding,并将原始的子组件(可能已经被包装在 MediaQuery 组件中)作为 SliverPadding 的子组件。
  5. 最后,它返回一个只包含一个组件(可能是 SliverPadding 或 MediaQuery 或原始的子组件)的列表。

这个实现确保了滚动视图的子组件可以正确地处理 padding,并且如果存在 MediaQuery,还可以自动适应 MediaQuery 的 padding。

5. buildChildLayout方法部分

less 复制代码
/// 子类应重写此方法以构建布局模型。
@protected
Widget buildChildLayout(BuildContext context);

参见《Flutter.源码分析.ScrollView》 buildChildLayout 部分,地址 blog.csdn.net/qq_28550263...

6. 其它代码

typescript 复制代码
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
  super.debugFillProperties(properties);
  properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding, defaultValue: null));
}

这里的 debugFillProperties 方法是用于支持 Flutter 的诊断工具的。当开发者要求查看 BoxScrollView 的属性时,这个方法会被调用。在这个方法中,BoxScrollView 将自己的 padding 属性添加到了诊断属性中。这样,开发者就可以看到 padding 属性的值,以及它是否被设置了默认值。

相关推荐
君蓦2 小时前
Flutter 本地存储与数据库的使用和优化
flutter
problc12 小时前
Flutter中文字体设置指南:打造个性化的应用体验
android·javascript·flutter
lqj_本人20 小时前
鸿蒙next选择 Flutter 开发跨平台应用的原因
flutter·华为·harmonyos
lqj_本人1 天前
Flutter&鸿蒙next 状态管理框架对比分析
flutter·华为·harmonyos
起司锅仔1 天前
Flutter启动流程(2)
flutter
hello world smile1 天前
最全的Flutter中pubspec.yaml及其yaml 语法的使用说明
android·前端·javascript·flutter·dart·yaml·pubspec.yaml
lqj_本人1 天前
Flutter 的 Widget 概述与常用 Widgets 与鸿蒙 Next 的对比
flutter·harmonyos
iFlyCai1 天前
极简实现酷炫动效:Flutter隐式动画指南第二篇之一些酷炫的隐式动画效果
flutter
lqj_本人1 天前
Flutter&鸿蒙next 中使用 MobX 进行状态管理
flutter·华为·harmonyos