当前位置:   article > 正文

Jetpack Compose 初体验教程,不会真还有人不会用吧?_jetpack compose 缺点

jetpack compose 缺点

概览

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!")
    }
}
复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 该函数需要有@Composable注解,所有Compose相关的函数都需要有这个注解,这个注解的作用是告诉编译器该函数是用来生成UI的。
  • 该函数可以接受参数,这些参数可以让应用逻辑来描述界面,比如上面的这个函数,接收一个字符串名字,这个名字就可以影响界面的显示
  • 该函数中Column()相当于之前xml中的LinearLayout,Text()相当于之前xml中的TextVIew

使用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")})
    }
}
复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

remember是一个可以保存Composable中的数值的函数,只是临时保存,Composable移除后也会跟着移除或者被打断后。

想要被打断之后还能保存状态,比如来电了,可以使用rememberSaveable

我们可以使用MutableState来观察数据的状态从而动态更新界面。除了使用MutableState之外,还可以使用LiveData、Flow、Rxjava2,使用这几个的时候我们需要将其转化为State接口,这样才能让compose识别。

比如LiveData中的转换,给LiveData设置一个扩展方法,也是使用remember创建一个state并返回。

@Composable
fun <R, T : R> LiveData<T>.observeAsState(initial: R): State<R> {
    val lifecycleOwner = LocalLifecycleOwner.current
    val state = remember { mutableStateOf(initial) }
    DisposableEffect(this, lifecycleOwner) {
        val observer = Observer<T> { state.value = it }
        observe(lifecycleOwner, observer)
        onDispose { removeObserver(observer) }
    }
    return state
}
复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

一般情况下数据不会直接放在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")})
    }
}
复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

HelloScreen 负责数据状态的更改逻辑,HelloContent负责UI的展示和事件的传递。

使用ViewModel

使用ViewModel来管理数据的状态

class HelloViewModel:ViewModel() {
    private val _name = MutableLiveData("")
    val name : LiveData<String> = _name

    fun onNameChanged(newName:String){
        _name.value = newName
    }
}
复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

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")})
    }
}
复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

上面代码中 observeAsState可以观察LiveData,并返回State ,State Jetpack Compose 可以直接使用的可观察类型。前面说了observeAsState内部也是封装了remember函数。使用的时候需要引入下面的依赖

implementation "androidx.compose.runtime:runtime-livedata:1.0.0-beta01"
复制代码
  • 1
  • 2

Jetpack Compose是通过各个组件的组合来描述一个UI界面,当应用的状态发生变化的时候,Jetpack Compose 会安排重组,重组就是重新执行可能因状态改变而发生变化的组件。重组是更新界面的唯一方式。

也就是说一个组合就可以代表一个界面,其内部的可组合项的生命周期就是:进入组合、执行0次或者多次重组、退出组合。

Compose中的重组一般是由State<T>接口触发,Compose会跟踪使用State<T>数据的可组合项,Compose在重组的时候只会更改发生变化的部分。

下面来了解一下常用的布局、列表、动画、手势等操作在Compose中的使用。

布局

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/254196
推荐阅读
相关标签
  

闽ICP备14008679号