Flutter 在 3.24 版本中增加了 CarouselView 组件,它是一个符合 Material Design 风格的轮播组件。目前该组件已经收录到 【FlutterUnit】 中,文中的代码可以详见其中的案例:
- | - |
---|---|
1. CarouselView 官方案例
官方案例效果如下所示,滑动过程中前面条目会逐渐变窄,后面条目会逐渐变宽。CarouselView
组件构造函数中:
- itemExtent: 滑动方向上条目的尺寸。
- shrinkExtent: 滑动方向上条目可缩短到的尺寸。
- children: 轮播中的内容组件。
右滑 | 左滑 |
---|---|
return Center(
child: ConstrainedBox(
constraints: const BoxConstraints(maxHeight: 200),
child: CarouselView(
itemExtent: 330,
shrinkExtent: 200,
children: List<Widget>.generate(20, (int index) {
return UncontainedLayoutCard(index: index, label: 'Item $index');
}),
),
),
);
可以看出,CarouselView 会强制影响内容条目在滑动方向上的尺寸。也就是水平滑动时,即使设置条目的宽度会被无视,你也无法让 CarouselView 支持不同高度的条目轮播。
2. FlutterUnit 提供的案例
FlutterUnit 中提供了另一个小案例,如下所示,组件条目信息通过 CarouselView 实现轮播:
从 CarouselView 的构造函数来看,itemExtent
和 children
是必须传入的。另外还有很多其他的配置参数:
将 itemSnapping
置为 true, 可以启用滑到大于下一个一半时自动滑入,反之回到上一个条目的功能:
CarouselView(
backgroundColor: const Color(0xfff7f8fa),
itemExtent: 240,
shrinkExtent: 240,
itemSnapping: true,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(6)),
children: widgets.map((e) => _WidgetDisplay(widget: e)).toList(),
),
下面是 CarouselView 组件所有的属性介绍:
字段名称 | 类型 | 描述 | 默认值 |
---|---|---|---|
padding | EdgeInsets? | 用于围绕每个轮播项的空间量。 | EdgeInsets.all(4) |
backgroundColor | Color? | 每个轮播项的背景颜色。 | ColorScheme.surface |
elevation | double? | 每个轮播项的 z 轴高度(阴影效果)。 | 0.0 |
shape | ShapeBorder? | 每个轮播项的形状。 | RoundedRectangleBorder ,圆角半径 28.0 |
overlayColor | WidgetStateProperty<Color?>? | 用于在按下、悬停或聚焦状态时的高亮颜色。 | 主题相关 |
shrinkExtent | double | 在滚动过渡期间每个轮播项在主轴方向的最小允许尺寸。 | 0.0 |
itemSnapping | bool | 轮播是否应继续滚动到下一个/上一个项目以保持原始布局。 | false |
controller | CarouselController? | 用于控制滚动视图位置的对象。 | null |
scrollDirection | Axis | 滚动视图的偏移随着每个项目的增加的方向。 | Axis.horizontal |
reverse | bool | 轮播列表是否按照阅读方向滚动。 | false |
onTap | ValueChanged<int>? | 当点击其中一个 children 时调用的回调函数。 | null |
itemExtent | double | 子元素在主轴方向上必须具有的尺寸。 | 无默认值,必须设置 |
children | List<Widget> | 轮播的子元素。 | 无默认值,必须设置 |
3. CarouselView 源码简看
打开 _CarouselViewState
状态类类结构面板,可以到 build 方法中使用的组件。CarouselView 构造函数中的属性也都用在这些组件的构建中:
最上层的 LayoutBuilder 用于获取父级的约束信息,根据滑动轴向得到h滑动方向的最大尺寸: _itemExtend
:
整体来看,可滑动的能力由 Scrollable + Viewport 组合实现。视口中的滑片是自定义的 _SliverFixedExtentCarousel
:
这个滑片和 SliverList 是一个等级的,在构造中传入两个 Extend 尺寸; 其中也能通过 delegate 入参,使用 SliverChildBuilderDelegate 根据索引构建子条目(下面紫框)。子条目的边距、背景色、边距等是和 CarouselView 构造入参相关的:
总得来看,CarouselView 使用上是非常简单的,源码上也不是非常复杂。反之它的局限性也比较大,它需要在一开始就实例化所有的子组件,不太适合海量或无限的条目。另外控制器的作用也很有限,无法感知条目滑动的当前索引,这样就无法处理指示器。如果需要更复杂的处理, 可以使用 PageView 组件。
更多文章和视频知识资讯,大家可以关注我的公众号、掘金和 B 站 。