官方支持Compose轮播图组件啦~

前言

在此之前如果我们想要在Compose中实现轮播图的效果,一般需要借助HorizontalPager来实现,需要自己额外处理定时刷新的逻辑。在m3中官方为我们提供了标准的轮播图Carousel组件,现在Carousel也支持Compose了,借助Carousel可以轻松在Compose中实现轮播图的效果。

Carousel分类

在原生View系统中,Carousel为我们提供了四种布局,分别为:

  • Multi-browse
  • Uncontained
  • Hero
  • Full-screen

提供了两种滚动方式:

  • Default: 默认值: 标准滚动。
  • Snap-scrolling: 对齐滚动: 滚动条对齐Carousel的布局。推荐用于多浏览

在这里插入图片描述

而在Compose中提供了HorizontalMultiBrowseCarousel、HorizontalUncontainedCarousel 两个方法。 今天我们只来了解如何在Compose中使用Carousel组件。

使用方法

准备工作

新建Compose项目,将m3升级到最新版本,因为部分API仍处于实验性阶段。

implementation("androidx.compose.material3:material3:1.3.0-beta05")

准备好要展示的图片,代码如下所示:

data class CarouselItem(
    val id: Int,
    @DrawableRes val imageResId: Int,
    @StringRes val contentDescriptionResId: Int
)

val items =
    listOf(
        CarouselItem(0, R.drawable.carousel_image_1, R.string.carousel_image_1_description),
        CarouselItem(1, R.drawable.carousel_image_2, R.string.carousel_image_2_description),
        CarouselItem(2, R.drawable.carousel_image_3, R.string.carousel_image_3_description),
        CarouselItem(3, R.drawable.carousel_image_4, R.string.carousel_image_4_description)
    )

HorizontalMultiBrowseCarousel

HorizontalMultiBrowseCarousel的参数如下所示。

@ExperimentalMaterial3Api
@Composable
fun HorizontalMultiBrowseCarousel(
    state: CarouselState,
    preferredItemWidth: Dp,
    modifier: Modifier = Modifier,
    itemSpacing: Dp = 0.dp,
    flingBehavior: TargetedFlingBehavior = CarouselDefaults.singleAdvanceFlingBehavior(state = state),
    minSmallItemWidth: Dp = CarouselDefaults.MinSmallItemSize,
    maxSmallItemWidth: Dp = CarouselDefaults.MaxSmallItemSize,
    contentPadding: PaddingValues = PaddingValues(0.dp),
    content: @Composable CarouselItemScope.(itemIndex: Int) -> Unit
): Unit

主要参数含义如下:

参数名含义
CarouselState用来控制Carousel的状态
preferredItemWidth水平轴上的宽度,这个宽度是一个目标,可能会通过Carousel来调整,以适应容器中的整个项目数量
itemSpacingItem之间的分隔间距
contentCarousel中的内容

接下来我们实现HorizontalMultiBroseCarousel方法,代码如下所示:

@ExperimentalMaterial3Api
@Composable
fun Carouse(){
    HorizontalMultiBrowseCarousel(
        state = rememberCarouselState { items.count() } ,
        modifier = Modifier.width(412.dp).height(221.dp),
        preferredItemWidth = 186.dp,
        itemSpacing = 8.dp,
        contentPadding = PaddingValues(horizontal = 16.dp)
    ) { i ->
val item = items[i]
        Image(
            modifier = Modifier.height(205.dp).maskClip(MaterialTheme.shapes.extraLarge),
            painter = painterResource(id = item.imageResId),
            contentDescription = stringResource(item.contentDescriptionResId),
            contentScale = ContentScale.Crop
        )
    }
}

运行程序,结果如下图所示。

在这里插入图片描述

这里需要注意,如果我们将preferredItemWidth改为0dp,即使给Image设置宽度自适应 也是无法生效的。

HorizontalUncontainedCarousel

HorizontalUncontainedCarousel的参数如下所示。

@ExperimentalMaterial3Api
@Composable
fun HorizontalUncontainedCarousel(
    state: CarouselState,
    itemWidth: Dp,
    modifier: Modifier = Modifier,
    itemSpacing: Dp = 0.dp,
    flingBehavior: TargetedFlingBehavior = CarouselDefaults.noSnapFlingBehavior(),
    contentPadding: PaddingValues = PaddingValues(0.dp),
    content: @Composable CarouselItemScope.(itemIndex: Int) -> Unit
)

与HorizontalMultiBrowseCarousel不同的是preferredItemWidth变成了itemWidth参数。

实现代码,如下所示:

HorizontalUncontainedCarousel(
    state = rememberCarouselState { items.count() } ,
    modifier = Modifier.width(412.dp).height(221.dp),
    itemWidth = 186.dp,
    itemSpacing = 8.dp,
    contentPadding = PaddingValues(horizontal = 16.dp)
) { i ->
val item = items[i]
    Image(
        modifier = Modifier.height(205.dp).maskClip(MaterialTheme.shapes.extraLarge),
        painter = painterResource(id = item.imageResId),
        contentDescription = stringResource(item.contentDescriptionResId),
        contentScale = ContentScale.Crop
    )
} 

运行程序,结果如下图所示。

在这里插入图片描述

乍一看效果好像与HorizontalUncontainedCarousel没有什么区别,但是仔细一看,好像也没什么区别。

这里的itemWidth相当于指定了滚动项的固定宽度,但实际不会超过屏幕宽度。而preferredItemWidth是期望的宽度,Carouse会根据实际情况进行动态调整。

rememberCarouselState

在上述两个方法中都有一个rememberCarouselState,它的使用方法也很简单,除了itemCount参数之外还有一个initialItem参数,用于指定初始卡片的位置。用法如下所示。

state = rememberCarouselState(initialItem = 3) { items.count() } 

最后

2024年了,还有人不会Compose吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黄林晴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值