You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jetpack Compose中实现环形轮播动画?

在Jetpack Compose中实现环形轮播效果

要实现你提供的这种环形轮播(中间Item放大、两侧Item缩小且支持无限循环滑动),可以基于HorizontalPager通过无限循环页码处理和自定义页面变换效果来实现,具体方案如下:

步骤1:添加Pager依赖

确保项目中引入Compose Pager库:

implementation "androidx.compose.foundation:foundation-pager:1.3.1"

步骤2:完整实现代码

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.scale
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

// 定义轮播Item的数据结构
data class CarouselItem(val imageRes: Int, val title: String)

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun CircularCarousel(
    items: List<CarouselItem>,
    autoScrollDelay: Long = 3000 // 自动轮播间隔(毫秒)
) {
    if (items.isEmpty()) return

    // 初始化Pager状态:初始页设为Int.MAX_VALUE的一半,保证左右都能无限滑动
    val pagerState = rememberPagerState(
        initialPage = Int.MAX_VALUE / 2,
        pageCount = { Int.MAX_VALUE }
    )
    val coroutineScope = rememberCoroutineScope()

    // 自动轮播逻辑(不需要可删除)
    LaunchedEffect(Unit) {
        while (true) {
            delay(autoScrollDelay)
            pagerState.animateScrollToPage(pagerState.currentPage + 1)
        }
    }

    HorizontalPager(
        state = pagerState,
        modifier = Modifier.fillMaxWidth().height(250.dp),
        contentPadding = PaddingValues(horizontal = 40.dp), // 两侧留空,显示部分相邻Item
        pageSpacing = 16.dp // 页面间间距
    ) { page ->
        // 通过取模获取真实Item索引,实现无限循环
        val realIndex = page % items.size
        val item = items[realIndex]

        // 计算页面偏移量,用于调整缩放和透明度
        val pageOffset = (pagerState.currentPage - page) + pagerState.currentPageOffsetFraction
        val scale = 1f - (pageOffset.absoluteValue * 0.2f) // 中间页面缩放1f,两侧缩至0.8f
        val alpha = 1f - (pageOffset.absoluteValue * 0.3f) // 中间完全不透明,两侧半透明

        Box(
            modifier = Modifier
                .fillMaxSize()
                .scale(scale)
                .alpha(alpha),
            contentAlignment = Alignment.BottomCenter
        ) {
            Image(
                painter = painterResource(id = item.imageRes),
                contentDescription = item.title,
                modifier = Modifier.fillMaxSize(),
                contentScale = ContentScale.Crop
            )
            Text(
                text = item.title,
                modifier = Modifier.padding(16.dp),
                color = androidx.compose.ui.graphics.Color.White
            )
        }
    }
}

// 使用示例
@Composable
fun CarouselDemo() {
    val demoItems = listOf(
        CarouselItem(R.drawable.carousel_img1, "夏日海滩"),
        CarouselItem(R.drawable.carousel_img2, "雪山风光"),
        CarouselItem(R.drawable.carousel_img3, "城市夜景"),
        CarouselItem(R.drawable.carousel_img4, "森林秘境")
    )
    CircularCarousel(items = demoItems)
}

关键逻辑说明

  1. 无限循环实现:

    • 将Pager总页数设为Int.MAX_VALUE,通过page % items.size映射到真实Item索引,滑动时永远不会触达边界。
    • 初始页设为Int.MAX_VALUE / 2,确保左右有足够虚拟页码可滑动。
  2. 环形视觉效果:

    • 通过pageOffset计算Item与中间页的偏移程度,动态调整缩放和透明度,让中间Item最大最清晰,两侧Item逐渐缩小变透明。
    • contentPadding让两侧Item显示部分内容,增强环形沉浸感。
  3. 自定义调整:

    • 修改scale和alpha的系数(如0.2f改0.15f),可调整视觉效果强弱;
    • 调整contentPadding、pageSpacing控制两侧Item显示范围;
    • 修改autoScrollDelay可调整自动轮播间隔,不需要自动轮播可直接删除对应代码。

内容的提问来源于stack exchange,提问作者Abdullah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 05:27:43