需求:在Row或者column中,设置某个组件的宽度或者高度为百分比。
常规方式
使用fillMaxWidth(0.3f)的方式设置宽度为可用宽度的30%
使用weight的方式设置权重,间接设置百分比宽高
遇到的问题
我在一个Row中,设置ABC三个组件的宽度都是fillMaxWidth(0.3f),效果并不像想象中的,每个组件的宽度都相同
测试:
Row(modifier = Modifier.width(100.dp).background(Color.Red)) {
Text("A", modifier = Modifier.fillMaxWidth(0.5f).background(Color.Blue))
Text("B", modifier = Modifier.fillMaxWidth(0.5f).background(Color.Yellow))
Text("C", modifier = Modifier.fillMaxWidth(0.5f).background(Color.Green))
}
效果如下:
看到A是占了总宽度的一半,B是占了剩余宽度的一半,C又是占了计算后剩余宽度的一半
得出结论,在Row容器中,Modifier.fillMaxWidth(0.5f)是设置宽度为可用宽度的一半
吐槽:使用ai得出的结论都是错误的:
使用Widget的方式设置时需要注意。使用Spacer
常见的情况下,一个组件在设置Modifier的第一项为padding的时候,表现是我们以前的Margin效果
但是,使用weight的时候,要注意这一点。 比如一个Row中,三个组件,都设置weight为1,表示它们三个平分可用空间
这时候就要注意,比如想为某个组件通过padding的方式设置margin,那么就会出现错误效果,比如
Row(modifier = Modifier.width(300.dp).height(50.dp).background(Color.Gray)) {
Text(text = "111", modifier = Modifier.weight(1f).background(Color.Red))
Text(text = "111", modifier = Modifier.padding(start = 40.dp).weight(1f).background(Color.Blue))
Text(text = "111", modifier = Modifier.weight(1f).background(Color.Magenta))
}
明显,设置的padding也算在组件的尺寸中了
这时候就要使用Spacer来设置margin了
Column(modifier = Modifier.fillMaxWidth().fillMaxHeight().padding(top = 50.dp)) {
Row(modifier = Modifier.width(300.dp).height(50.dp).background(Color.Gray)) {
Text(text = "111", modifier = Modifier.weight(1f).background(Color.Red))
Spacer(modifier = Modifier.width(40.dp))
Text(text = "111", modifier = Modifier.weight(1f).background(Color.Blue))
Text(text = "111", modifier = Modifier.weight(1f).background(Color.Magenta))
}
}
这样才是平分可用空间。
自己计算,使用固定尺寸
比如我有一个可用空间,但是不知道它的实际尺寸,我想在内部设置一些组件,设置宽高为它的30%。如何实现?
获取可用空间的宽高
使用Modifier.onGloballyPosition函数,获取组件的尺寸,位置的相关信息
计算需要的尺寸,设置到对应的组件上
// 观察尺寸变化
var layoutWidth by remember {
mutableIntStateOf(0)
}
var layoutHeight by remember {
mutableIntStateOf(0)
}
// 进行尺寸转换和计算
val density = LocalDensity.current
val itemHeight = with(density) {
(layoutHeight.toDp() - 20.dp) / 3
}
LazyVerticalGrid(
columns = GridCells.Fixed(2),
verticalArrangement = Arrangement.spacedBy(10.dp),
horizontalArrangement = Arrangement.spacedBy(10.dp),
modifier = modifier
.fillMaxSize()
.onGloballyPositioned { coordinates -> // 获取当前组件尺寸
val size = coordinates.size
layoutWidth = size.width
layoutHeight = size.height
},
) {
itemsIndexed(tipsList) { index, item ->
Text(
text = item,
textAlign = TextAlign.Center,
color = Color.White,
fontSize = 30.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier
.fillMaxWidth()
.height(itemHeight)
.clip(shape = RoundedCornerShape(5.dp))
.background(
color = if (index == 2) colorResource(R.color.orange) else colorResource(
R.color.teal_700
)
)
.wrapContentHeight(align = Alignment.CenterVertically)
)
}
}
这样,我设置的item的高度就是组件总高度-20dp后的三分之一