Compose组件转换XML布局

打印 上一主题 下一主题

主题 1748|帖子 1748|积分 5244

学习JetPack Compose资源

学习资源:JetPack Compose博物馆
媒介:

在JetPack Compose博物馆中,对于compose的讲解较为详细,我这篇笔记主要是记载自己不懂和不理解的知识点,可能会重复,也可能有其他的,学习Compose布局一样平常都是从传统XML布局中进行转换的,接下来开始学习不同布局的Compose组件。
预览界面的实现

1、在传统的XML文件中,都是可以一边填写代码一边查看页面,在Compose如何实现呢?
首先,对一个无参的方法添加@Preview和@Composable的注解,如下图所示
  1. @Preview(showBackground = true)
  2. @Composable
  3. fun GreetingPreview() {
  4.     ChainOfCustodyTheme {
  5.             Text(
  6.                 text = "Hello Android!",
  7.                 modifier = Modifier.fillMaxSize().wrapContentSize(Alignment.Center), // 内容居中
  8.             )
  9.     }
  10. }
复制代码
2、上述的图标分别为Code 、Split、Design,选择Split就可以看到分屏显示,默以为左右分屏,再次点击Split图标可以切换为上下分屏。

3、在添加注解的方法中,有个小图标,点击可直接在设备中运行该方法,不需要全部运行了。如下图所示

Compose组件的布局管理

一、Row和Colum组件(LinearLayout)

看字面意思可知,Row对应XML布局中LinearLayout的水平布局,Colum对应XML布局中LinearnLayout的垂直布局
LinearLayout(垂直方向 → Column)

根本用法:
  1. @Composable
  2. fun VerticalList() {
  3.     Column(
  4.         modifier = Modifier
  5.             .fillMaxWidth()
  6.             .padding(16.dp),
  7.         verticalArrangement = Arrangement.SpaceEvenly // 垂直分布方式
  8.     ) {
  9.         Text("Item 1")
  10.         Text("Item 2")
  11.         Text("Item 3")
  12.     }
  13. }
复制代码
等效于:
  1. <LinearLayout
  2.     android:layout_width="match_parent"
  3.     android:layout_height="wrap_content"
  4.     android:orientation="vertical">
  5.     <TextView ... />
  6.     <TextView ... />
  7.     <TextView ... />
  8. </LinearLayout>
复制代码
LinearLayout(水平方向 → Row)

权重分配
  1. @Composable
  2. fun HorizontalWeight() {
  3.     Row(modifier = Modifier.fillMaxWidth()) {
  4.         Text(
  5.             text = "Left",
  6.             modifier = Modifier
  7.                 .weight(1f) // 占剩余空间的1/3
  8.                 .background(Color.Gray)
  9.         )
  10.         Text(
  11.             text = "Right",
  12.             modifier = Modifier
  13.                 .weight(2f) // 占剩余空间的2/3
  14.                 .background(Color.LightGray)
  15.         )
  16.     }
  17. }
复制代码
等效于
  1. <LinearLayout
  2.     android:layout_width="match_parent"
  3.     android:orientation="horizontal">
  4.     <TextView
  5.         android:layout_width="0dp"
  6.         android:layout_weight="1" .../>
  7.     <TextView
  8.         android:layout_width="0dp"
  9.         android:layout_weight="2" .../>
  10. </LinearLayout>
复制代码
二、相对布局 FrameLayout → Box

叠加元素
  1. @Composable
  2. fun OverlayElements() {
  3.     Box(modifier = Modifier.fillMaxSize()) {
  4.         Image(
  5.             painter = painterResource(R.drawable.background),
  6.             contentDescription = null,
  7.             modifier = Modifier.matchParentSize()
  8.         )
  9.         Button(
  10.             onClick = { /* ... */ },
  11.             modifier = Modifier.align(Alignment.BottomEnd) // 右下角对齐
  12.         ) {
  13.             Text("Action")
  14.         }
  15.     }
  16. }
复制代码
等效于
  1. <FrameLayout ...>
  2.     <ImageView ... />
  3.     <Button
  4.         android:layout_gravity="bottom|end" ... />
  5. </FrameLayout>
复制代码
三、RelativeLayout → ConstraintLayoutBox

使用ConstraintLayout需要额外添加依赖,注意需要和传统ConstrainLayout区分开来
依赖添加:
  1. implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha13")
复制代码
1. 用 ConstraintLayout 实现相对定位

  1. @Composable
  2. fun RelativePositioning() {
  3.     ConstraintLayout(modifier = Modifier.fillMaxWidth()) {
  4.         val (button, text) = createRefs()
  5.         
  6.         Button(
  7.             onClick = { /* ... */ },
  8.             modifier = Modifier.constrainAs(button) {
  9.                 start.linkTo(parent.start)
  10.                 top.linkTo(parent.top)
  11.             }
  12.         ) { Text("Button") }
  13.         Text(
  14.             text = "Next to Button",
  15.             modifier = Modifier.constrainAs(text) {
  16.                 start.linkTo(button.end, margin = 16.dp)
  17.                 top.linkTo(button.top)
  18.             }
  19.         )
  20.     }
  21. }
复制代码
2. 用 Box 实现简单相对布局

  1. Box(modifier = Modifier.fillMaxSize()) {
  2.     Text("Center", modifier = Modifier.align(Alignment.Center))
  3.     Text("Top Start", modifier = Modifier.align(Alignment.TopStart))
  4. }
复制代码

五、GridLayout → LazyVerticalGrid 或自定义行/列

1. 网格布局

直接调用组件LazyVerticalGrid既可以完成实现
  1. LazyVerticalGrid(
  2.     columns = GridCells.Fixed(2), // 2列
  3.     modifier = Modifier.fillMaxWidth()
  4. ) {
  5.     items(10) { index ->
  6.         Card(
  7.             modifier = Modifier
  8.                 .padding(8.dp)
  9.                 .aspectRatio(1f)
  10.         ) {
  11.             Box(modifier = Modifier.background(Color.LightGray)) {
  12.                 Text("Item $index", modifier = Modifier.align(Alignment.Center))
  13.             }
  14.         }
  15.     }
  16. }
复制代码

六、TableLayout → 嵌套 Row 和 Column

  1. @Composable
  2. fun TableExample() {
  3.     Column(modifier = Modifier.padding(16.dp)) {
  4.         // 表头行
  5.         Row(modifier = Modifier.fillMaxWidth()) {
  6.             Text(
  7.                 text = "Header 1",
  8.                 modifier = Modifier.weight(1f).padding(8.dp)
  9.             )
  10.             Text(
  11.                 text = "Header 2",
  12.                 modifier = Modifier.weight(2f).padding(8.dp)
  13.             )
  14.         }
  15.         Divider(color = Color.Black, thickness = 1.dp)
  16.         // 数据行
  17.         Row(modifier = Modifier.fillMaxWidth()) {
  18.             Text(
  19.                 text = "Data 1",
  20.                 modifier = Modifier.weight(1f).padding(8.dp)
  21.             )
  22.             Text(
  23.                 text = "Data 2",
  24.                 modifier = Modifier.weight(2f).padding(8.dp)
  25.             )
  26.         }
  27.     }
  28. }
复制代码

七、ScrollView → Modifier.verticalScrollLazyColumn

1. 简单滚动

  1. Column(
  2.     modifier = Modifier
  3.         .fillMaxSize()
  4.         .verticalScroll(rememberScrollState())
  5. ) {
  6.     repeat(50) { index ->
  7.         Text("Item $index", modifier = Modifier.padding(8.dp))
  8.     }
  9. }
复制代码
2. 惰性滚动(大数据集用 LazyColumn)

  1. LazyColumn {
  2.     items(1000) { index ->
  3.         Text("Item $index", modifier = Modifier.padding(8.dp))
  4.     }
  5. }
复制代码

八、Space → Spacer

  1. Row {
  2.     Text("Left")
  3.     Spacer(modifier = Modifier.weight(1f)) // 占满剩余空间
  4.     Text("Right")
  5. }
复制代码

九、include 标签 → @Composable 函数

1. 定义可复用组件

  1. @Composable
  2. fun Header(title: String) {
  3.     Text(
  4.         text = title,
  5.         style = MaterialTheme.typography.h4,
  6.         modifier = Modifier.padding(16.dp)
  7.     )
  8. }
  9. // 在父布局中调用
  10. Column {
  11.     Header("Settings")
  12.     // 其他内容...
  13. }
复制代码


总结对比表

传统布局Compose 替换方案关键特性LinearLayout(垂直)ColumnverticalArrangement 控制垂直间距LinearLayout(水平)RowhorizontalArrangement 控制水平间距FrameLayoutBoxalign 控制子项对齐方式RelativeLayoutConstraintLayout通过 linkTo 定义束缚关系GridLayoutLazyVerticalGrid固定列数或自适应列宽TableLayout嵌套 Row 和 Column通过 weight 实现单元格比例ScrollViewModifier.verticalScroll简单滚动内容ListView/RecyclerViewLazyColumn/LazyRow惰性加载 + 主动复用SpaceSpacer空白占位include@Composable 函数直接调用自定义组件
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

半亩花草

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表