多个viewmodel之间的通信有多种方法,比如通过resposity将sharedviewmodel作为参数传递,进而完成数据通信,也可以通过一个公共的全局变量进行数据传递。本文中提供一个以singleton单例的方式进行。
1.创建单例的resposity类。
Kotlin
class testResposity private constructor(){
//创建单例
companion object{
private var INSTANCE:testResposity?=null
@Synchronized
fun getInstance():testResposity{
if(INSTANCE==null)
INSTANCE = testResposity()
return INSTANCE!!
}
}
//以下为业务逻辑
val data = MutableStateFlow<String>("")
val _counter1 = MutableStateFlow<Int>(0)
val counter1 = _counter1.asStateFlow()
fun updateCounter1()
{
_counter1.value++
if(_counter1.value==2)
{
data.value = "second"
}
else if(_counter1.value == 3)
{
data.value = "third"
}
}
}
2.创建测试的viewmodel1
Kotlin
class TestViewModel1:ViewModel() {
//获取resposity单例
private val resposity = testResposity.getInstance()
val data = resposity.data
//调用测试逻辑
public fun updateCounter1(){
resposity.updateCounter1()
}
}
3.按照相同的方式,创建测试的viewmodel2
Kotlin
class TestViewModel2:ViewModel() {
private val resposity = testResposity.getInstance()
val counter = resposity.counter1
public fun updateCounter(){
resposity.updateCounter1()
}
}
4.测试的compose
Kotlin
@Composable
fun TestViewModelScreen(modifier: Modifier = Modifier,
viewModel:TestViewModel1,
viewModel2:TestViewModel2,
onClicked:()->Unit,
onClicked2:()->Unit
) {
val counter1 = viewModel.data.collectAsState()
val counter2 = viewModel2.counter.collectAsState();
Column {
Text(text = counter1.value.toString())
Text(text = counter2.value.toString())
Button(modifier = Modifier,
onClick = onClicked
) {
Text(text = "更新")
}
Button(
modifier=Modifier,
onClick = onClicked2
) {
Text(text="更新2")
}
}
}
5.Activity中调用代码
Kotlin
var viewModel1=ViewModelProvider(this).get(TestViewModel1::class.java)
var viewModel2 = ViewModelProvider(this).get(TestViewModel2::class.java)
TestViewModelTheme {
Surface(
modifier = Modifier.fillMaxSize(),
)
{
Row (
modifier = Modifier.fillMaxSize(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
){
TestViewModelScreen(
viewModel = viewModel1,
viewModel2=viewModel2,
onClicked = {
viewModel1.updateCounter1()
},
onClicked2 = {
viewModel2.updateCounter()
}
)
}
}
}
6.结果
通过两个不同的viewModel,可以对仓库类中的一个变量进行操作,并同步可显示双方操作结果。