在命令式 UI 里,当订阅到 LiveData
数据变化时可明确指定 View 去刷新变化的值,比如 label.text = newValue
,但是声明式 UI 里由于无法指示界面更新,需要为 UI 分配值,当值发生变化,界面会自动刷新, Compose 的 State<T>
负责此自动“重绘“(在 Compose 中,被称为 recomposition
)。因此,需要将 LiveData
转换为 State
。
添加依赖
除了 ViewModel
依赖还需要另一个依赖项将 LiveData
转换为 State
implementation "androidx.compose.runtime:runtime-livedata:1.1.0-beta03"
创建 ViewModel
class MainViewModel : ViewModel() {
val counterLiveData: LiveData<Int>
get() = counter
private val counter = MutableLiveData<Int>()
private var count = 0
fun increaseCounter() {
counter.value = ++count
}
}
一个简单的 ViewModel 持有一个用于计数的 Counter 使用 LiveData<Int>
创建 View
@Composable
fun CounterScreen(model: MainViewModel = viewModel()) {
val count by model.counterLiveData.observeAsState(0)
val text = "This is $count"
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.White),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
BasicText(text)
Button(
onClick = {
model.increaseCounter()
},
) {
BasicText(text = "Add 1")
}
}
}
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Surface(color = Color.White) {
CounterScreen()
}
}
}
}
viewModel()
默认值将返回现有的ViewModel
,或在调用中创建一个新 ViewModel。无需在Activity
单独保存ViewModel
实例。- 在这里需要将
LiveData<Int>
转换为Int
,可以直接用于 View。每当有新值时,都会有一个 Compose’sState<Int>
负责“重新组合”视图。0
是初始状态。
Done!
Github
Done!
[外链图片转存中…(img-