Android的Compose概览

文章目录

  • Compose概览
    • compose是什么
      • 声明式
        • 声明式更新
    • 组合函数
    • 状态state
      • var value by remember { mutableStateOf(default) }
        • mutableStateOf
        • remember
        • rememberSaveable
    • 状态提升
      • 接入ViewModel和LiveData使用
    • Modifier

Compose概览

官方文档
我个人看了下官方的文档,尝试了一下demo,大概做一个个人的理解和记录,还没有深入研究尝试

compose是什么

Android推出的新的,以声明式语言方式,用来进行UI编写的UI库

声明式

常见的是与命令式比较出现,我们以前的常用的是就是命令式语言编写的UI
看了一些介绍的文章,简单的一点理解就是:

命令式编程就像王刚教你做菜,会告诉你每一步做什么
声明式就是直接把材料给王刚,告诉他要吃什么菜,做菜的人是王刚

关于Compose的声明式UI,暂时能感受到的:

  1. 不用写xml文件了
  2. 直接调用compose的库就可以在界面渲染出组件
  3. 猜想这种编写方式以后会方便复用(比如我复用一个compose函数,比复用一个xml+java要简单吧)

声明式更新

扔物线视频
扔物线视频中提到,声明式的重点在于可以自动更新页面,而dataBinding更新的是页面的数据,使用compose的声明式可以更新页面的数据和其他属性,甚至是结构

组合函数

@compose注解的函数,注释告诉编译器,此函数旨在将数据转换为界面,用组合函数作为参数的时候,也要声明有@compose注解

组合函数可以调用其他的组合函数,不会返回任何内容

状态state

简单来说,就是会影响界面发生变化的变量
状态的变化会引起其所在compose函数重构

var value by remember { mutableStateOf(default) }

官方例子中的写法,还提到有其他写法:

val mutableState = remember { mutableStateOf(default) }
var value by remember { mutableStateOf(default) }
val (value, setValue) = remember { mutableStateOf(default) }

mutableStateOf

创建一个可观察的状态变量,持有单一值。当这个变量变化的时候,会引起函数重组,相关部分界面重新渲染

remember

缓存了状态变量的值

rememberSaveable

这个是相对于remember的,当横竖屏切换的时候,使用remember是不能保存状态值的,使用rememberSaveable就可以

状态提升

这个没有理解清除,但是看代码的意思,是把状态部分抽出去进行了封装

未进行状态提升的时候

@Composable
fun HelloContent() {
   Column(modifier = Modifier.padding(16.dp)) {
       var name by remember { mutableStateOf("") }
       if (name.isNotEmpty()) {
           Text(
               text = "Hello, $name!",
               modifier = Modifier.padding(bottom = 8.dp),
               style = MaterialTheme.typography.h5
           )
       }
       OutlinedTextField(
           value = name,
           onValueChange = { name = it },
           label = { Text("Name") }
       )
   }
}

官方的例子:进行状态提升后

@Composable
fun HelloScreen() {
	var name by rememberSaveable { mutableStateOf("") }

	HelloContent(name = name, onNameChange = { name = it })
}

@Composable
fun HelloContent(name: String, onNameChange: (String) -> Unit) {
    Column(modifier = Modifier.padding(16.dp)) {
        Text(
            text = "Hello, $name",
            modifier = Modifier.padding(bottom = 8.dp),
            style = MaterialTheme.typography.h5
        )
        OutlinedTextField(
            value = name,
            onValueChange = onNameChange,
            label = { Text("Name") }
        )
    }
}

如果按照之前的写法,那么name应该是在helloContent中的,我们直接调用helloContent,提升后,我们要调用helloScreen,这样做的好处,官方的总结:

以这种方式提升的状态具有一些重要的属性:

单一可信来源:我们会通过移动状态而不是复制状态,来确保只有一个可信来源。这有助于避免 bug。
封装:只有有状态可组合项能够修改其状态。这完全是内部的。
可共享:可与多个可组合项共享提升的状态。如果想在另一个可组合项中执行 name 操作,可以通过变量提升来做到这一点。
可拦截:无状态可组合项的调用方可以在更改状态之前决定忽略或修改事件。
解耦:无状态 ExpandingCard 的状态可以存储在任何位置。例如,现在可以将 name 移入 ViewModel。

个人理解,也就是这个状态可能影响多个部分,我们把状态封装后,统一状态,统一处理

接入ViewModel和LiveData使用

class HelloViewModel : ViewModel() {

    // LiveData holds state which is observed by the UI
    // (state flows down from ViewModel)
    private val _name = MutableLiveData("")
    val name: LiveData = _name

    // onNameChange is an event we're defining that the UI can invoke
    // (events flow up from UI)
    fun onNameChange(newName: String) {
        _name.value = newName
    }
}


@Composable
fun HelloScreen(helloViewModel: HelloViewModel = viewModel()) {
    // by default, viewModel() follows the Lifecycle as the Activity or Fragment
    // that calls HelloScreen(). This lifecycle can be modified by callers of HelloScreen.

    // name is the current value of [helloViewModel.name]
    // with an initial value of ""
    val name: String by helloViewModel.name.observeAsState("")
    HelloContent(name = name, onNameChange = { helloViewModel.onNameChange(it) })
}

@Composable
fun HelloContent(name: String, onNameChange: (String) -> Unit) {
    Column(modifier = Modifier.padding(16.dp)) {
        Text(
            text = "Hello, $name",
            modifier = Modifier.padding(bottom = 8.dp),
            style = MaterialTheme.typography.h5
        )
        OutlinedTextField(
            value = name,
            onValueChange = onNameChange,
            label = { Text("Name") }
        )
    }
}

很明显的,是替换掉了
remember { mutableStateOf(default) } 这种方式,以
ViewModel.name.observeAsState("") 方式实现

Modifier

官方文档和例子
修饰符,可以用来设置渲染的布局,尺寸等,修饰符声明的顺序很重要,因为是按顺序渲染的

你可能感兴趣的:(Android的Compose概览)