Android Compose : 传统View在Compose组件中的等价物

传统View在Compose组件中的等价物

对于刚接触Compose的Android开发者来说,最想知道的莫过于:我在传统View的界面组件,用Compose怎么来实现呢 ?

1. 常见组件

1.1 TextView

TextView文本,在Compose中,对应的是Text

kotlin 复制代码
Text("Hello World")

可以给Text设置一个颜色,比如这里讲文本设置为白色

kotlin 复制代码
Text("Hello World", color = Color.White)

1.2 ImageView

ImageView图片,在Compose中,对应的是Image,Image有两个参数是必填的 :

  • painter : 用来指定要显示的图像资源,是 Compose 中处理图像绘制的核心载体,替代了传统 View 体系中的 Drawable
  • contentDescription : 用来支持 Android 无障碍服务提供图像的语义含义,如无需该功能,可传入null
kotlin 复制代码
Image(painter = painterResource(R.drawable.ic_navi), contentDescription = null)

1.3 Button

Button按钮,在Compose中,对应的也是Button,Compose中的Button由两个组件构成,Button本身是一个容器,还有一个用来展示具体内容的组件,比如Text

kotlin 复制代码
Button(onClick = {}) {
    Text("Click me")
}

Compose为什么要这么设计呢 ? 为什么要用两个组件来实现一个按钮,合并成一个组件不好吗 ?

答案是这样做能够更动态,这也是Compose这么设计相较于传统View的优势了。

比如我需要展示一个带Icon的Button,那直接多添加一行代码增加一个Image组件,就可以实现了。

kotlin 复制代码
Button(onClick = {}) {
    Image(painter = painterResource(R.drawable.ic_navi), contentDescription = null)
    Text("Click me")
}

那如果想改个背景颜色,圆角啥的,也很简单,直接在构造方法里传入就行

kotlin 复制代码
Button(
    onClick = {},
    colors = ButtonDefaults.buttonColors(containerColor = Color.DarkGray),
    shape = RoundedCornerShape(12.dp)
) {
    Image(painter = painterResource(R.drawable.ic_navi), contentDescription = null)
    Text("Click me")
}

如果想把Button内部的组件竖向排列呢 ? 也很简单,套一层Column组件就行

kotlin 复制代码
Button(
    onClick = {},
    colors = ButtonDefaults.buttonColors(containerColor = Color.DarkGray),
    shape = RoundedCornerShape(12.dp)
) {
    Column(horizontalAlignment = Alignment.CenterHorizontally) {
        Image(painter = painterResource(R.drawable.ic_navi), contentDescription = null)
        Text("Click me")
    }
}

既然讲到了Column,我们就来讲下Compose中的常见布局。

2. 常见布局

2.1 LinearLayout

LinearLayout在Compose中,对应的是Column和Row,Column是竖向的,而Row是横向的。

kotlin 复制代码
Column {
    Image(painter = painterResource(R.drawable.ic_navi), contentDescription = null)
    Text("Hello World", color = Color.White)
}

我们 将 Column 替换为 Row ,可以看到就变成横向排列了

kotlin 复制代码
Row {
    Image(painter = painterResource(R.drawable.ic_navi), contentDescription = null)
    Text("Hello World", color = Color.White)
}

2.2 FrameLayout

FrameLayout在Compose中,对应的是Box,其作用也是一样的,默认是叠着放。

kotlin 复制代码
Box {
    Image(painter = painterResource(R.drawable.ic_navi), contentDescription = null)
    Text("Hello World", color = Color.White)
}

2.3 RelativeLayout

RelativeLayout在Compose中,没有对应的组件。那要怎么实现类似RelativeLayout的功能呢 ?

直接用Box、Column、Row多套几层来写就行。

你可能会有疑问了,这样写不会造成性能问题吗 ? 在Android传统View中,最禁忌的就是嵌套布局的写法,会造成性能指数级的下降。

答案是不会,在Compose中,布局层级嵌套,几乎不会造成性能损耗。

为啥呢 ? 因为Compose在约束不变、内容 / 样式不变的前提下,每个节点仅测量一次,所以所以不再需要RelativeLayout这种工具了。

2.4 ConstraintLayout

ConstraintLayout可以理解为RelativeLayout的加强版,同样在Compose中,直接用Box、Column、Row多套几层来写就行了。

ConstraintLayout是有Compose版本的,但是那是在Compose还不完善的时候,需要实现特定功能时会用ConstraintLayout,而现在Compose功能逐渐完善了,Compose版的ConstraintLayout就已经完成其历史使命了。

2.5 RecyclerView

RecyclerView在Compose中,对应使用的是 LazyColumn / LazyRow。

相比传统View中的Recyclerview,Compose中不需要写 Adapter + ViewHolder + XML 布局这些大量的模板代码, LazyColumn 仅需几行声明式代码即可替代。

kotlin 复制代码
val data = mutableListOf("item1", "item2", "item3", "item4", "item5")

LazyColumn {
    items(data) {
        Text(text = it, color = Color.White)
    }
}

而且在Compose中,可以很方便的添加Header和Footer,相比之下Recyclerview就要麻烦多了。

kotlin 复制代码
val data = mutableListOf("item1", "item2", "item3", "item4", "item5")

LazyColumn {
    item { Text(text = "Header", color = Color.White) }
    items(data) {
        Text(text = it, color = Color.White)
    }
    item { Text(text = "Footer", color = Color.White) }
}

给item添加click事件也很容易

kotlin 复制代码
val data = mutableListOf("item1", "item2", "item3", "item4", "item5")

LazyColumn {
    item { Text(text = "Header", color = Color.White) }
    items(data) {
        Text(text = it, modifier = Modifier.clickable { //给item添加点击事件
            toast(it)
        }, color = Color.White)
    }
    item { Text(text = "Footer", color = Color.White) }
}

2.6 ScrollView

ScrollView和Recyclerview的区别是,它内部的滑动组件不是动态的而是预先写好的。在Compose中,要实现和ScrollView同样的效果,只需要在Modifier中添加verticalScroll,就实现竖向的ScrollView的效果了。

如果是横向的ScrollView,那就改成Row和Modifier.horizontalScroll就行。

kotlin 复制代码
Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
    Text("item1", color = Color.White)
    Text("item2", color = Color.White)
    Text("item3", color = Color.White)
    Text("item4", color = Color.White)
    Text("item5", color = Color.White)
}

2.7 ViewPager

ViewPager,在Compose中应的是HorizontalPager/VerticalPager,横向滑动的是HorizontalPager,垂直方向滑动的是VerticalPager。

kotlin 复制代码
HorizontalPager(
    state = rememberPagerState(pageCount = { 3 }),
    modifier = Modifier.fillMaxWidth()
) { page ->
    Text(text = "第 ${page + 1} 页!")
}
相关推荐
Haha_bj11 分钟前
Flutter ——device_info_plus详解
android·flutter·ios
前端小伙计16 分钟前
Android/Flutter 项目统一构建配置最佳实践
android·flutter
Mr_sun.2 小时前
Day09——入退管理-入住-2
android·java·开发语言
ujainu3 小时前
告别杂乱!Flutter + OpenHarmony 鸿蒙记事本的标签与分类管理(三)
android·flutter·openharmony
常利兵4 小时前
Android内存泄漏:成因剖析与高效排查实战指南
android
·云扬·4 小时前
MySQL 8.0 Redo Log 归档与禁用实战指南
android·数据库·mysql
野生技术架构师4 小时前
SQL语句性能优化分析及解决方案
android·sql·性能优化
doupoa5 小时前
内存指针是什么?为什么指针还要有偏移量?
android·c++
非凡ghost6 小时前
PowerDirector安卓版(威力导演安卓版)
android·windows·学习·软件需求
独行soc6 小时前
2026年渗透测试面试题总结-19(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮