Flutter 组件集录 | CarouselView 轮播视图 @3.24

655 阅读3分钟

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 的构造函数来看,itemExtentchildren 是必须传入的。另外还有很多其他的配置参数:

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 组件所有的属性介绍:

字段名称类型描述默认值
paddingEdgeInsets?用于围绕每个轮播项的空间量。EdgeInsets.all(4)
backgroundColorColor?每个轮播项的背景颜色。ColorScheme.surface
elevationdouble?每个轮播项的 z 轴高度(阴影效果)。0.0
shapeShapeBorder?每个轮播项的形状。RoundedRectangleBorder,圆角半径 28.0
overlayColorWidgetStateProperty<Color?>?用于在按下、悬停或聚焦状态时的高亮颜色。主题相关
shrinkExtentdouble在滚动过渡期间每个轮播项在主轴方向的最小允许尺寸。0.0
itemSnappingbool轮播是否应继续滚动到下一个/上一个项目以保持原始布局。false
controllerCarouselController?用于控制滚动视图位置的对象。null
scrollDirectionAxis滚动视图的偏移随着每个项目的增加的方向。Axis.horizontal
reversebool轮播列表是否按照阅读方向滚动。false
onTapValueChanged<int>?当点击其中一个 children 时调用的回调函数。null
itemExtentdouble子元素在主轴方向上必须具有的尺寸。无默认值,必须设置
childrenList<Widget>轮播的子元素。无默认值,必须设置

3. CarouselView 源码简看

打开 _CarouselViewState 状态类类结构面板,可以到 build 方法中使用的组件。CarouselView 构造函数中的属性也都用在这些组件的构建中:

最上层的 LayoutBuilder 用于获取父级的约束信息,根据滑动轴向得到h滑动方向的最大尺寸: _itemExtend :

整体来看,可滑动的能力由 Scrollable + Viewport 组合实现。视口中的滑片是自定义的 _SliverFixedExtentCarousel :

这个滑片和 SliverList 是一个等级的,在构造中传入两个 Extend 尺寸; 其中也能通过 delegate 入参,使用 SliverChildBuilderDelegate 根据索引构建子条目(下面紫框)。子条目的边距、背景色、边距等是和 CarouselView 构造入参相关的:


总得来看,CarouselView 使用上是非常简单的,源码上也不是非常复杂。反之它的局限性也比较大,它需要在一开始就实例化所有的子组件,不太适合海量或无限的条目。另外控制器的作用也很有限,无法感知条目滑动的当前索引,这样就无法处理指示器。如果需要更复杂的处理, 可以使用 PageView 组件。

更多文章和视频知识资讯,大家可以关注我的公众号、掘金和 B 站 。