- Android: Jetpack Compose如何禁用涟漪(水波纹)效果
- Android:使用Jetpack Compose 实现Text控件跑马灯效果
- Android:使用Jetpack Compose实现自动轮播Banner
文章目录
- 系列文章目录
- 前言
- 一、先看效果
- 二、实现思路
- 三、源码
- 四、使用示例
- 总结
前言
自动轮播Banner 相信大多数APP 都会有此需求,本文主要是使用Compose 来实现自动无限轮播图效果。
一、先看效果 二、实现思路
- 无限循环
思路:这里是将item数量设为无限大,然后计算出原始数据集合中的对应数据进行展示。 - 定时切换
思路:使用LaunchedEffect启动协程,死循环并间隔1s进行Pager切换。
三、源码需要注意的是:在手势拖动时,要关闭定时切换。
代码如下:
@OptIn(ExperimentalPagerApi::class) @Composable fun Banner(imgs: ArrayList四、使用示例) { val pageCount = imgs.size val loopingCount = Int.MAX_VALUE val startIndex = loopingCount / 2 val pagerState = rememberPagerState(initialPage = startIndex) // 页码转换 fun pageMapper(index: Int) = (index - startIndex).floorMod(pageCount) Box { HorizontalPager( count = loopingCount, state = pagerState, modifier = Modifier .fillMaxWidth() .padding(top = 14.dp) .aspectRatio(2.45f) ) { index -> // 计算页面下标 val page = pageMapper(index) BannerItem(imgUrl = imgs[page]) } HorizontalPagerIndicator( pagerState = pagerState, activeColor = Blue, inactiveColor = WhiteAlpha50, indicatorWidth = 10.dp, indicatorHeight = 4.dp, spacing = 5.dp, pageCount = pageCount, pageIndexMapping = ::pageMapper, modifier = Modifier .align( Alignment.BottomCenter ) .padding(bottom = 8.dp) ) var underDragging by remember { mutableStateOf(false) } LaunchedEffect(key1 = Unit) { pagerState.interactionSource.interactions.collect { interaction -> when (interaction) { is PressInteraction.Press -> underDragging = true is PressInteraction.Release -> underDragging = false is PressInteraction.Cancel -> underDragging = false is DragInteraction.Start -> underDragging = true is DragInteraction.Stop -> underDragging = false is DragInteraction.Cancel -> underDragging = false } } } if (underDragging.not()) { LaunchedEffect(key1 = underDragging) { try { while (true) { delay(1000L) val current = pagerState.currentPage val currentPos = pageMapper(current) val nextPage = current + 1 if (underDragging.not()) { val toPage = nextPage.takeIf { nextPage < pagerState.pageCount } ?: (currentPos + startIndex + 1) if (toPage > current) { pagerState.animateScrollToPage(toPage) } else { pagerState.scrollToPage(toPage) } } } } catch (e: CancellationException) { } } } } } @Composable fun BannerItem(imgUrl: String) { Box(modifier = Modifier.fillMaxSize()) { AsyncImage( model = imgUrl, contentDescription = null, contentScale = ContentScale.Crop, modifier = Modifier .fillMaxWidth() .padding(start = 16.dp, end = 16.dp) .clip(RoundedCornerShape(12.dp)) .clickable { // 点击事件 } ) } } private fun Int.floorMod(other: Int): Int = when (other) { 0 -> this else -> this - floorDiv(other) * other }
代码如下:
val bannerImg = remember {
mutableStateOf(
arrayListOf("https://gd-hbimg.huaban.com/e9198b5ec234b5f0b0e4473acf39b430ac47c1ee3f875-CjGaUR_fw658",
"https://gd-hbimg.huaban.com/e9198b5ec234b5f0b0e4473acf39b430ac47c1ee3f875-CjGaUR_fw658",
"https://gd-hbimg.huaban.com/e9198b5ec234b5f0b0e4473acf39b430ac47c1ee3f875-CjGaUR_fw658")
)
}
// 自动轮播图
Banner(bannerImg.value)
总结
以上就是今天要讲的内容,本文的源码已全部贴出,方便大家自取并快速使用。



