前情提要
本篇文章主要对 Compose 中的 Column 进行使用解析,文章结束会使用 Column 和 Row 配合实现一个淘宝商品 Item 的效果,
最终效果预览:
如果您对 Column 的用法比较娴熟,可以直接看最后一节的内容
Column 简单说明
Column 对应于我们开发中的 LinearLayout.vertical,可以垂直的摆放内部控件
因为 Row 和 Column 是想通的,只不过 Column 是垂直方向布局的,而 Row 是水平方向布局。所以讲完了 Column 你只需要把例子代码中的 Column 换成 Row 就可以自行查看 Row 的效果了
Column 参数介绍
modifier
用来定义 Column 的各种属性,比如可以定义宽度、高度、背景等
- 示例代码
设置 modifier 的时候可以链式调用
@Composable fun DefaultPreview() { Column(modifier = Modifier .width(300.dp) .height(200.dp) .background(color = Color.Green)) { } } 复制代码
- 实现效果
展示了一个绿色填充的矩形
verticalArrangement
实现内部元素的竖直对齐效果
关于 verticalArrangement 我们的示例代码如下
后面介绍每种效果的时候会更改 verticalArrangement 的值进行展示
Row() { Spacer(modifier = Modifier.width(100.dp)) Column( modifier = Modifier .width(50.dp) .height(200.dp) .background(color = Color.Green), // verticalArrangement = Arrangement.SpaceAround ) { Image(modifier = Modifier.size(20.dp),painter = painterResource(id = R.drawable.apple), contentDescription = null) Image(modifier = Modifier.size(20.dp),painter = painterResource(id = R.drawable.apple), contentDescription = null) Image(modifier = Modifier.size(20.dp),painter = painterResource(id = R.drawable.apple), contentDescription = null) Image(modifier = Modifier.size(20.dp),painter = painterResource(id = R.drawable.apple), contentDescription = null) } } 复制代码
不设置该属性的效果
- 效果
- 结论
不设置该属性的时候,内部元素贴着顶部紧凑排列
Arrangement.Center
- 效果
- 结论
所有元素垂直居中,紧凑排列
Arrangement.SpaceBetween
- 效果
- 结论
元素之间均分空间,与顶部和底部之间无间距
SpaceAround 效果
- 效果
- 结论
内部元素等分空间,并且顶部和底部留间距(顶部元素距离顶部的距离和底部元素距离底部的距离与元素等分的长度不一致)
Arrangement.SpaceEvenly
- 效果
- 结论
所有元素均分空间(顶部元素距离顶部的距离和底部元素距离底部的距离与元素等分的长度一致)
Arrangement.Bottom
- 效果
- 结论
所有元素靠近底部,紧凑排列
Arrangement.spacedBy(*.dp)
可以设置元素间的等分距离
比如我们设置 20dp,Arrangement.spacedBy(20.dp)
- 效果
- 结论
元素之间距离为 20dp,靠近顶部排列
horizontalAlignment
实现 Column 的水平约束
Alignment.Start 居开始的位置对齐
- 效果
- 结论
当前模拟器 Start 就是 Right,所以内部元素居左侧对齐
Alignment.CenterHorizontally 水平居中
- 效果
- 结论
内部元素水平居中对齐
Alignment.End
- 效果
- 结论
当前模拟器 End 就是 Left,所以内部元素居右侧对齐
content
关于这个属性,注释中都没写他我也就先不研究了
使用 Column 实现淘宝商品 item 布局
- 本例中目标效果图如下
- 代码
@Composable fun DefaultPreview2() { Row( modifier = Modifier.fillMaxSize(1f).background(color= Color.Gray), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Center ) { Column( modifier = Modifier .width(200.dp) .background(color = Color.White) .padding(all = 10.dp) ) { Image( painter = painterResource(id = R.drawable.apple), contentDescription = null, modifier = Modifier.size(180.dp).clip(RoundedCornerShape(10.dp)) ) Text( text = "当天发,不要钱", fontSize = 20.sp, style = TextStyle(fontWeight = FontWeight.Bold), modifier = Modifier.padding(vertical = 2.dp) ) Row( modifier = Modifier.padding(vertical = 2.dp), verticalAlignment = Alignment.CenterVertically ) { Text( text = "¥说了不要钱", fontSize = 14.sp, color = Color(0xff9f8722) ) Text(text = "23人免费拿", fontSize = 12.sp) } Row( modifier = Modifier .width(200.dp) .fillMaxWidth() .padding(vertical = 2.dp), verticalAlignment = Alignment.CenterVertically ) { Text(text = "不要钱") Spacer(modifier = Modifier.weight(1f))//通过设置weight让Spacer把Row撑开,实现后面的图片居右对齐的效果 Image( painter = painterResource(id = android.R.drawable.btn_star_big_on), contentDescription = null, ) } } } } 复制代码
- 实现说明
本商品 item 分为四部分:
第一部分:图片,我们使用 Image 实现
第二部分:商品描述,使用一个 Text
第三部分:价格,使用 Row 套两个 Text 实现
第四部分:分期情况,使用 Row 套一个 Text 和 Image 完成,注意因为图片要居右对齐,所以中间需要使用一个 Spacer 挤满剩余宽度。
淘宝商品 item 实现要点
- 我们可以使用 modifier = Modifier .width(200.dp) 设置 Column 的宽度
- Modifier.padding(all = 10.dp)可以设置四个方向的内边距
- modifier = Modifier.size(180.dp).clip(RoundedCornerShape(10.dp)可以设置圆角,因为本例中图片背景和控件背景都是白色,所以看不出来效果
- 最底部的控件需要让收藏按钮贴近父控件右侧对齐,使用 Modifier.weight 实现: Spacer(modifier = Modifier.weight(1f))