我正在尝试将共享视图模型用于活动和活动中显示的片段,因为两者都需要由视图模型更新。该片段使用 MutableLiveData 不断更新,但活动不是,我真的不明白为什么。出于可读性原因,我确实删除了 .xml 文件中与问题无关的布局参数。 我的活动代码如下所示:
class MainActivity : AppCompatActivity() {
private lateinit var _binding : MainActivityBinding
private val _viewModel : MySharedViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
_binding = DataBindingUtil.setContentView(this, R.layout.main_activity)
_binding.viewModel = _viewModel
_binding.lifecycleOwner = this
...
}
}
绑定的生命周期所有者已设置,但 MutableLiveData 似乎并未更新活动。 在活动布局文件中如下:
<layout>
<data>
<variable
name="viewModel"
type="com.customApp.viewModels.MySharedViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.appbar.MaterialToolbar>
<TextView
android:id="@+id/totalTime"
android:text="@{viewModel.topBarText}"
.../>
</com.google.android.material.appbar.MaterialToolbar>
<com.google.android.material.bottomnavigation.BottomNavigationView
.../>
<androidx.fragment.app.FragmentContainerView
.../>
</androidx.constraintlayout.widget.ConstraintLayout>
所以我有带有文本视图的顶部栏,始终显示文本,底部导航视图作为标签栏和包含片段的片段容器视图。
片段代码为:
class FirstFragment : Fragment() {
private val _viewModel : MySharedViewModel by viewModels()
private lateinit var _binding : FirstFragmentBinding
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
_binding = DataBindingUtil.inflate(inflater, R.layout.first_fragment, container, false)
_binding.viewModel = _viewModel
_binding.lifecycleOwner = viewLifecycleOwner
return _binding.root
}
}
此外,这里为绑定设置了生命周期所有者,并在片段布局中将其绑定到视图模型:
<layout>
<data>
<variable
name="viewModel"
type="com.customApp.viewModels.MySharedViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout>
<TextView
...
android:text="@{viewModel.fragmentText}" />
<Button
android:id="@+id/startButton"
android:onClick="@{() -> viewModel.startIteration()}"
.../>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
在我的视图模型中,我只是更新应显示的文本:
class MySharedViewModel : ViewModel() {
var topBarText : MutableLiveData<String> = MutableLiveData<String>("Hi")
var fragmentText : MutableLiveData<String> = MutableLiveData<String>("There")
private val stringsForTop = arrayOf("Hi","How", "You")
private val stringsForFragment = arrayOf("There","Are", "?")
private var index = 0
fun startIteration() {
kotlin.concurrent.fixedRateTimer(initialDelay = 1L, period = 1000L) {
viewModelScope.launch(Dispatchers.Main) {
topBarText.value = stringsForTop[index]
fragmentText.value = stringsForFragment[index]
index++
}
}
}
}
现在更新片段文本时,顶部栏中的文本不会更新,始终只显示“嗨”。我有一种感觉,当片段被初始化并且它的 viewLifecycleOwner 绑定到视图模型时,视图模型的生命周期观察者的活动会被覆盖。 我是否遗漏了某些东西,或者是否有另一种方法可以在视图模型中向其生命周期所有者注册活动和片段?任何帮助表示赞赏。