Jetpack Compose 是用来构建Android界面的新款工具包,前段时间beta版本刚发布的时候就已经心痒难耐的想要尝试了,最近轻松点了赶紧尝试一波。
以前我们都是通过xml布局,通过findViewById()找到控件之后手动给控件赋值。这样的缺点首先是解析xml生成view对象需要通过反射浪费性能,然后是手动给控件赋值容易出错,比如过个地方控制一个view的显示和隐藏,随着控制它的地方越来越多,维护起来也越来越复杂。
这几年,整个行业都开始向声明式界面模型转换,这个模型大大的简化了我们构建界面的流程。在更新界面的时候可以智能的找到应该更新的部分并且只刷新此部分的视图。
Compose就是一个声明式的UI框架
为了更好的边写Jetpack Compose ,最好下载Androidstudio的 最新 Canary 版的 Android Studio 预览版。他可以跟我们使用的release版本共存。使用它创建项目的时候直接有内置的创建Compose项目的模板。
简单了解一个Compose函数:
@Composable
fun Greeting(name: String) {
Column (modifier = Modifier.padding(16.dp)){
Text(text = "Hello $name!")
Text(text = "你好 $name!")
}
}
复制代码
使用Compose的时候需要注意
Compose的状态
下面的函数可以实现一个在文本框中输入文字的时候,动态的更改Text显示的内容
@Composable
fun HelloContent(){
Column(modifier = Modifier.padding(16.dp)) {
var name = remember{ mutableStateOf("")}
if(name.value.isNotEmpty()){
Text(text = "Hello,${name.value}",
modifier = Modifier.padding(8.dp),
style = MaterialTheme.typography.h5)
}
OutlinedTextField(value = name.value, onValueChange = { name.value = it },label = {Text("Name")})
}
}
复制代码
remember是一个可以保存Composable中的数值的函数,只是临时保存,Composable移除后也会跟着移除或者被打断后。
想要被打断之后还能保存状态,比如来电了,可以使用rememberSaveable
我们可以使用MutableState来观察数据的状态从而动态更新界面。除了使用MutableState之外,还可以使用LiveData、Flow、Rxjava2,使用这几个的时候我们需要将其转化为State接口,这样才能让compose识别。
比如LiveData中的转换,给LiveData设置一个扩展方法,也是使用remember创建一个state并返回。
@Composable
fun LiveData.observeAsState(initial: R): State {
val lifecycleOwner = LocalLifecycleOwner.current
val state = remember { mutableStateOf(initial) }
DisposableEffect(this, lifecycleOwner) {
val observer = Observer { state.value = it }
observe(lifecycleOwner, observer)
onDispose { removeObserver(observer) }
}
return state
}
复制代码
一般情况下数据不会直接放在Composable修饰的方法里面而是提出来比如下面的代码,这样更容易代码的复用和管理
@Composable
fun HelloScreen(){
var name = remember{ mutableStateOf("")}
HelloContent(name = name.value, onNmeChange = { name.value = it })
}
@Composable
fun HelloContent(name: String,onNmeChange:(String)->Unit){
Column(modifier = Modifier.padding(16.dp)) {
if(name.isNotEmpty()){
Text(text = "Hello,${name}",
modifier = Modifier.padding(8.dp),
style = MaterialTheme.typography.h5)
}
OutlinedTextField(value = name, onValueChange = onNmeChange,label = {Text("Name")})
}
}
复制代码
HelloScreen 负责数据状态的更改逻辑,HelloContent负责UI的展示和事件的传递。
使用ViewModel
使用ViewModel来管理数据的状态
class HelloViewModel:ViewModel() {
private val _name = MutableLiveData("")
val name : LiveData = _name
fun onNameChanged(newName:String){
_name.value = newName
}
}
复制代码
MainActivity中
private val viewModel:HelloViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApplicationTheme {
Surface(color = MaterialTheme.colors.background) {
Column {
HelloScreen(viewModel)
}
}
}
}
}
@Composable
fun HelloScreen(viewModel: HelloViewModel){
val name:String by viewModel.name.observeAsState("")
HelloContent(name = name, onNmeChange = { viewModel.onNameChanged(it) })
}
@Composable
fun HelloScreen(){
var name = remember{ mutableStateOf("")}
HelloContent(name = name.value, onNmeChange = { name.value = it })
}
@Composable
fun HelloContent(name: String,onNmeChange:(String)->Unit){
Column(modifier = Modifier.padding(16.dp)) {
if(name.isNotEmpty()){
Text(text = "Hello,${name}",
modifier = Modifier.padding(8.dp),
style = MaterialTheme.typography.h5)
}
OutlinedTextField(value = name, onValueChange = onNmeChange,label = {Text("Name")})
}
}
复制代码
上面代码中 observeAsState可以观察LiveData,并返回State ,State Jetpack Compose 可以直接使用的可观察类型。前面说了observeAsState内部也是封装了remember函数。使用的时候需要引入下面的依赖
implementation "androidx.compose.runtime:runtime-livedata:1.0.0-beta01"
复制代码
Jetpack Compose是通过各个组件的组合来描述一个UI界面,当应用的状态发生变化的时候,Jetpack Compose 会安排重组,重组就是重新执行可能因状态改变而发生变化的组件。重组是更新界面的唯一方式。
也就是说一个组合就可以代表一个界面,其内部的可组合项的生命周期就是:进入组合、执行0次或者多次重组、退出组合。
Compose中的重组一般是由State
接口触发,Compose会跟踪使用State
数据的可组合项,Compose在重组的时候只会更改发生变化的部分。
下面来了解一下常用的布局、列表、动画、手势等操作在Compose中的使用。
Compose中