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 属性的值,以及它是否被设置了默认值。

相关推荐
yuanlaile8 小时前
Flutter小白零基础入门到高级项目实战全集
flutter·dart·flutter开发鸿蒙
顾林海12 小时前
Flutter Dart 元数据:为代码注入额外信息
android·前端·flutter
kkkrrrf19 小时前
dart学习记录4(循环、分钟、错误处理)
dart
sunly_1 天前
Flutter:页面滚动,导航栏背景颜色过渡动画
开发语言·javascript·flutter
顾林海2 天前
Flutter Dart 异步支持全面解析
android·前端·flutter
小书房2 天前
Flutter中Align的使用说明
flutter·align
leluckys2 天前
flutter 专题 九十八 Flutter 1.7正式版发布
flutter
黎明故日2 天前
Flutter 谷歌地图与页面滑动冲突
flutter
顾林海2 天前
Flutter Dart 泛型详解
android·前端·flutter