今天大概会聊到的范围
- viewModel in Compose
今天的主题很单纯:如果专案中有使用到 Compose 又有用到 Android Architecture Component 的 ViewModel 与 LiveData 的话,要怎麽让资料在 Compose 内外传递呢?
首先,先建立今天的主角 ViewModel
class FooViewModel : ViewModel() {
val buzzLiveData: LiveData<List<String>>
get() = _buzzLiveData
private val _buzzLiveData = MutableLiveData<List<String>>(emptyList())
fun addData(param: String) {
_buzzLiveData.value = _buzzLiveData.value?.let { it + listOf(param) }
}
}
ViewModel 可以在 Activity 层建立,方法就和一般的 ViewModel 一样:
class BarActivity : ComponentActivity() {
private val vm: FooViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
FooComposable(vm) // <--
}
}
}
@Composable
fun FooComposable(vm: FooViewModel) { ... }
在 Activity 建立 ViewModel 後,可以将其当成一般的参数传入 Composable。
@Composable
fun FooComposable(model: FooViewModel) {
val data by model.buzzLiveData.observeAsState(initial = emptyList()) // <--- 1
Column {
LazyColumn {
items(data) { // <--- 2
Text(it)
}
}
Button({ model.addData("one") }) { // <--- 3
Text("add data")
}
}
}
observeAsState
需要implementation "androidx.lifecycle:lifecycle-viewmodel-compose:1.0.0-alpha07"
observeAsState
来将 LiveData 转换成 State注意!呼叫 ViewModel function 的部分若是放在 composable function 中,会变成 side-effect 。若真的要执行需要特别处理 ( 上一篇的主题 )
Button 的 onClick callback 不是 composable function
@Composable
fun FooComposable(model: FooViewModel = viewModel()) { ... }
若不一定要外部的使用者提供 ViewModel,也可以透过 viewModel()
来现场建立一个 viewModel。
observeAsState
Under the hoodobserveAsState
到底怎麽把 LiveData 转成 State 的呢?我们可以来研究一下 observeAsState
的实作:
@Composable
fun <R, T : R> LiveData<T>.observeAsState(initial: R): State<R> {
val lifecycleOwner = LocalLifecycleOwner.current // < --- 1
val state = remember { mutableStateOf(initial) } // < --- 2
DisposableEffect(this, lifecycleOwner) { // < --- 5
val observer = Observer<T> { state.value = it } // < --- 3
observe(lifecycleOwner, observer)
onDispose { removeObserver(observer) } // < --- 6
}
return state // < --- 4
}
LocalLifecycleOwner
可以取得目前 Composable 所在 scope 的 LifecycleOwner
remember { mutableStateOf() }
将资料存放起来LiveData.observe
去观察 LiveData 的资料,若有改动就将资料同步到 stateLiveData
or LifecycleOwner
有异动的时候能重新做 observe ,且除此之外不要做异动。使用之前提到过的 DisposableEffect
onDispose
时,将 observer 回收想不到 ViewModel 和 LiveData 在 Compose 中的使用其实非常的简单。在 LiveData 背後,又刚好是使用到之前所研究的 Side Effect API,感觉整个技术都串起来了!
Reference:
<<: 【Day 26】S3 on AWS Outpost 限制与建置流程
D15. 字元阵列(2) 前一篇有讲到字元的输出是printf("%c",a[i...
哈罗大家好,今天要做的是重设密码API,先附上我的程序码~~ 程序码 @csrf_protect d...
昨天讲的将函式(Function)加入型别相信大家都了解了, 今天就带大家来看看**完整函式型别(W...
前面介绍的程序都只有单一路径,今天要来讲更复杂的多路径的情况 运算子 比较运算子 说明 用法 ==...
在讨论MLOps的过程当中,许多客户会针对他们有兴趣的事情提出不同的问题,像是:模型监测、安全性、常...