降低非焦点项目的不透明度

2024-01-11

我有一个显示在主屏幕上的项目列表,该列表可以垂直滚动。目前我有 5 个项目,但当用户接近最后一个项目时会添加项目,从而创建无限滚动。

我想让所有项目淡出,但焦点所在的项目应该完全透明,如下所示:

正如您所看到的,左侧和右侧的项目已褪色并且稍小,而焦点中的项目是完全透明的并且稍大,表明这是焦点中的项目。

这是我的Composable list:

@Composable
fun HomeScreenList() {
    val homeScreenItems = getItems()
    val listState = rememberLazyListState(Int.MAX_VALUE / 2)
    LazyRow(
        state = listState,
        modifier = Modifier
            .fillMaxWidth(),
        contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp)
    ) {
        items(Int.MAX_VALUE, itemContent = {
            val index = it % homeScreenItems.size
            HomeScreenItem(model = homeScreenItems[index])
        })
    }
}

And the HomeScreenItem:

@Composable
fun HomeScreenItem(model: HomeScreenViewModel) {
    Card(
        modifier = Modifier
            .padding(horizontal = 10.dp, vertical = 20.dp),
        elevation = 2.dp,
        backgroundColor = model.mBackgroundColor,
        shape = Shapes.large,
    ) {
        Row {
             Image(
        painter = painterResource(id = model.mIcon),
        contentDescription = null,
        contentScale = ContentScale.Crop,
        modifier = Modifier
            .padding(20.dp)
            .size(100.dp)
    )
        }
    }
}

有谁知道我应该如何实现这一目标?


您可以使用列表状态来确定每个项目距中心有多远,并相应地应用不透明度:

val homeScreenItems = remember {
    listOf(
        Icons.Default.Person,
        Icons.Default.Usb,
        Icons.Default.Keyboard,
    )
}
val listState = rememberLazyListState(Int.MAX_VALUE / 2)
val (rowHalfSize, setRowHalfSize) = remember { mutableStateOf<Int?>(null) }
val horizontalContentPadding = 16.dp
val density = LocalDensity.current
LazyRow(
    state = listState,
    contentPadding = PaddingValues(horizontal = horizontalContentPadding, vertical = 8.dp),
    modifier = Modifier
        .fillMaxWidth()
        .onSizeChanged {
            setRowHalfSize(it.width / 2 - with(density) { horizontalContentPadding.roundToPx() })
        }
) {
    items(Int.MAX_VALUE) { globalIndex ->
        val index = globalIndex % homeScreenItems.size
        val opacity by remember(rowHalfSize) {
            derivedStateOf {
                if (rowHalfSize == null) return@derivedStateOf 0.5f
                val currentItemInfo = listState.layoutInfo.visibleItemsInfo
                    .firstOrNull() { it.index == globalIndex }
                    ?: return@derivedStateOf 0.5f
                val itemHalfSize = currentItemInfo.size / 2
                (1f - minOf(1f, abs(currentItemInfo.offset + itemHalfSize - rowHalfSize).toFloat() / itemHalfSize) * 0.5f)
            }
        }
        Icon(
            homeScreenItems[index], null,
            modifier = Modifier
                .alpha(opacity)
                .scale(opacity)
        )
    }
}

Result:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

降低非焦点项目的不透明度 的相关文章