如何在Jetpack Compose中同时实现盒子垂直居中与间距?
如何让Jetpack Compose LazyVerticalGrid同时实现垂直居中与项间距?
我有一个包含三个项的网格,希望所有盒子既能垂直居中,又能在彼此之间保留间距/内边距。当前代码使用verticalArrangement = Arrangement.spacedBy可以实现盒子间距,但改为verticalArrangement = Arrangement.Center后,盒子会居中却丢失了间距。试过使用Spacer但效果不佳,期望效果如下:
{: width="250"}
现有代码(带间距但不居中)
@Composable fun TopicGrid(modifier: Modifier = Modifier) { LazyVerticalGrid( columns = GridCells.Fixed(1), verticalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.padding_medium)), horizontalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.padding_large)), modifier = modifier ) { items(DataSource.topics) { topic -> TopicCard(topic) } } }
修改后代码(居中但无间距)
@Composable fun TopicGrid(modifier: Modifier = Modifier) { LazyVerticalGrid( columns = GridCells.Fixed(1), verticalArrangement = Arrangement.Center, horizontalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.padding_large)), modifier = modifier ) { items(DataSource.topics) { topic -> TopicCard(topic) } } }
解决方案
方法一:利用Box嵌套实现(推荐)
将LazyVerticalGrid包裹在Box中,让Box负责整体垂直居中,同时保留LazyVerticalGrid的间距设置,代码简洁易维护:
@Composable fun TopicGrid(modifier: Modifier = Modifier) { Box( modifier = modifier.fillMaxHeight(), contentAlignment = Alignment.Center ) { LazyVerticalGrid( columns = GridCells.Fixed(1), verticalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.padding_medium)), horizontalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.padding_large)), modifier = Modifier.wrapContentHeight() ) { items(DataSource.topics) { topic -> TopicCard(topic) } } } }
方法二:自定义Vertical Arrangement
如果需要更灵活的控制,可以自定义Arrangement.Vertical,同时实现居中逻辑和间距分配:
@Composable fun TopicGrid(modifier: Modifier = Modifier) { val spacing = dimensionResource(R.dimen.padding_medium) val verticalArrangement = object : Arrangement.Vertical { override fun Density.arrange(totalSize: Int, sizes: IntArray, outPositions: IntArray) { val totalItemHeight = sizes.sum() val totalSpacing = spacing.toPx() * (sizes.size - 1) val totalContentHeight = totalItemHeight + totalSpacing // 计算顶部偏移量实现整体居中 val topOffset = (totalSize - totalContentHeight) / 2 var currentOffset = topOffset.toInt() for (i in sizes.indices) { outPositions[i] = currentOffset currentOffset += sizes[i] + spacing.toPx().toInt() } } } LazyVerticalGrid( columns = GridCells.Fixed(1), verticalArrangement = verticalArrangement, horizontalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.padding_large)), modifier = modifier.fillMaxHeight() ) { items(DataSource.topics) { topic -> TopicCard(topic) } } }
两种方法都能实现你要的效果,其中方法一代码更简洁,适合大多数场景。
内容的提问来源于stack exchange,提问作者Vanessa Lau
相关产品推荐
相关产品推荐

