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} 页!")
}
相关推荐
神话20092 小时前
Rust 初体验与快速上手指南
android·rust
CheungChunChiu3 小时前
Linux 内核动态打印机制详解
android·linux·服务器·前端·ubuntu
aidou13144 小时前
Android中设置Dialog和自定义布局相同高度
android·dialog·弹窗高度·getwindow
氦客4 小时前
UI编程的发展史 : 结合命令式UI和声明式UI
android·compose·声明式ui·ui编程·命令式ui·ui编程发展史·标记语言
aidou13147 小时前
Android中RecyclerView实现多级列表
android·recyclerview·多级列表·layoutmanager
青风行7 小时前
Android从入门到进阶
android
方白羽7 小时前
Android 开发中,准确判断应用处于“前台(Foreground)”还是“后台(Background)
android·app·客户端
Mart!nHu8 小时前
Android 10&15 Framework 允许设置系统时间早于编译时间
android
编程之路从0到19 小时前
ReactNative新架构之Android端TurboModule机制完全解析
android·react native·源码阅读