fmtjava/Jetpack_GitHub

[疑问]请问怎么做到多页面共享一个viewmodel

qq326646683 opened this issue · 9 comments

  1. 需求场景:登录页面给UserViewModel里mUserInfoModel赋值。在Main页面里显示用户信息
  2. 实现:
class LoginActivity : BaseDataBindVMActivity<ActivityLoginBinding>() {
    private val mViewModel: UserViewModel by viewModel()


class MainActivity : BaseDataBindVMActivity<ActivityMainBinding>() {
    private val mViewModel: UserViewModel by viewModel()

  1. 结果:登录页面可以渲染赋值后的用户信息,Main页面不行
  2. 期望:登录页面和Main页面能共享用户信息数据

ps:我打印了两个页面的mViewModel,发现地址不一样,请问如何创建出多个页面共享的mViewModel

是要做到数据同步是吧,你可以用LiveData保存用户信息,将LiveData放到一个单例类中,获取或修改都通过单例类就可以了

我用单例试了一下,ui不重新渲染了

object UserInfoUI {
    val mUserModel = MutableLiveData<UserModel>()
}

//activity.kt:
mDataBind.mUserModel = UserInfoUI.mUserModel.value

//userViewModel.kt:
fun getUserInfo() {
        launch {
            UserInfoUI.mUserModel.value = mUserRepository.getUserInfo().obj
        }
    }

//xml:
<variable
            name="mUserModel"
            type="com.jinxian.wenshi.module_user.model.UserModel" />

<TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{mUserModel.phone}"/>

可以提供一下例子吗?最近刚接触android和kotlin,有点不熟

UserInfoUI.mUserModel.observe(this, Observer {
mDataBind.mUserModel = it
})
试一下这样

也不行哎

我写的Demo是下面这样的,不知道是否符合你的需求:
`class MainActivity : AppCompatActivity() {

lateinit var mDataBind: ActivityMainBinding

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    mDataBind = DataBindingUtil.setContentView(this, R.layout.activity_main)
    
    UserInfoUI.mUserModel.observe(this, Observer {
        mDataBind.mUserModel = it
    })

}

fun go2Second(view: View) {
    Intent(this, SecondActivity::class.java).also {
        startActivity(it)
    }
}

}

object UserInfoUI {
val mUserModel = MutableLiveData()
}

class UserModel(val phone: String)`

`class SecondActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
}

fun go2First(view: View) {
    val userModel = UserModel("15112453213")
    UserInfoUI.mUserModel.value = userModel
    finish()
}

}`

UserInfoUI.mUserModel.observe(this, Observer {
mDataBind.mUserModel = it
})
试一下这样

我又重新试了一下,可以了,多谢多谢,不过有个疑问,为什么你这样可以渲染UI:

   override fun initData() {
        mDataBind.userViewModel = mViewModel
        mViewModel.getUserInfo(mUser)
    }

而我 mDataBind.mUserModel = UserInfoUI.mUserModel.value 不行,为什么非得observe再赋值呢

UserInfoUI.mUserModel.observe(this, Observer {
mDataBind.mUserModel = it
})
试一下这样

我又重新试了一下,可以了,多谢多谢,不过有个疑问,为什么你这样可以渲染UI:

   override fun initData() {
        mDataBind.userViewModel = mViewModel
        mViewModel.getUserInfo(mUser)
    }

而我 mDataBind.mUserModel = UserInfoUI.mUserModel.value 不行,为什么非得observe再赋值呢

observe是用于订阅数据变化,当数据发生变化后会回到更新,而mDataBind.mUserModel = UserInfoUI.mUserModel.value只是做了一次赋值,并没有订阅事件

我看你先mDataBind.userViewModel = mViewModel ,再去获取信息进行赋值操作,这种是订阅的写法吗?我这边mDataBind.mUserModel = UserInfoUI.mUserModel.value赋值这么就不行呢,感觉写法一样

我看你先mDataBind.userViewModel = mViewModel ,再去获取信息进行赋值操作,这种是订阅的写法吗?我这边mDataBind.mUserModel = UserInfoUI.mUserModel.value赋值这么就不行呢,感觉写法一样

你先去了解一下DataBinding与LiveData的使用吧,了解后就应该能明白了