如何在Jetpack Compose Horizontal Pager中实现图片缩放效果
Jetpack Compose HorizontalPager 实现中间原图、两侧缩放的无限滚动效果
要实现中间图片保持原尺寸、滑动时两侧图片缩放的效果,核心是根据页面偏移量动态计算缩放比例,并通过动画让过渡更平滑。修改你的代码如下:
@OptIn(ExperimentalFoundationApi::class) @Composable fun CustomSlider( modifier: Modifier = Modifier, sliderList: MutableList<String>, pagerPaddingValues: PaddingValues = PaddingValues(horizontal = 65.dp), imageCornerRadius: Dp = 16.dp, imageHeight: Dp = 240.dp, minScale: Float = 0.8f // 两侧图片最小缩放比例 ) { val pageCount = Int.MAX_VALUE val pagerState = rememberPagerState(initialPage = pageCount / 2) Column( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { Row( modifier = modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Center, ) { HorizontalPager( pageCount = pageCount, state = pagerState, contentPadding = pagerPaddingValues, modifier = modifier.weight(1f) ) { page -> // 计算当前页与目标页的偏移量,处理无限滚动的索引偏移 val adjustedPage = page % sliderList.size val currentAdjustedPage = pagerState.currentPage % sliderList.size val pageOffset = when { // 处理滚动到边界时的无限偏移计算 currentAdjustedPage == sliderList.size - 1 && adjustedPage == 0 -> { pagerState.currentPageOffsetFraction - 1f } adjustedPage == sliderList.size - 1 && currentAdjustedPage == 0 -> { pagerState.currentPageOffsetFraction + 1f } else -> { (pagerState.currentPage - page) + pagerState.currentPageOffsetFraction } } // 计算缩放值:偏移量绝对值越大,缩放比例越小,最小到minScale val scale = animateFloatAsState( targetValue = 1f - (kotlin.math.abs(pageOffset) * (1f - minScale)), animationSpec = tween(durationMillis = 200) ).value Box( modifier = modifier .padding(10.dp) .clip(RoundedCornerShape(imageCornerRadius)) ) { AsyncImage( model = ImageRequest.Builder(LocalContext.current) .scale(Scale.FILL) .crossfade(true) .data(sliderList[adjustedPage]) .build(), contentDescription = "轮播图片", contentScale = ContentScale.Crop, placeholder = painterResource(id = R.drawable.img), modifier = modifier .height(imageHeight) .width(295.dp) .scale(scale) // 应用缩放效果 ) } } } } }
关键修改说明:
- 缩放比例计算:通过
pageOffset的绝对值计算缩放值,当前选中页面的偏移量为0,缩放比例保持1f;两侧页面随偏移量增大,缩放比例线性减小到设置的minScale(默认0.8f)。 - 平滑动画:使用
animateFloatAsState让缩放过渡更自然,避免生硬的尺寸变化。 - 无限滚动偏移修正:处理无限滚动时,当滚动到列表首尾衔接的位置,修正
pageOffset的计算逻辑,避免缩放出现异常。
效果预览:
内容的提问来源于stack exchange,提问作者pepperlove
相关产品推荐
相关产品推荐

