Android ViewModel 双向绑定不起作用
Android ViewModel two way binding is not working
我正在尝试学习如何使用 MVVM,以及 Android 中的双向数据绑定。我非常熟悉 MVVM 和来自其他 languages/frameworks(.net、Angular 等)
的双向数据绑定
所以,据我所知,我想要一个 viewModel 来保留数据,我还想要一个 repository,我将把它传递给服务(例如播放音频文件)
我按照 this tutorial 设置了视图模型,但我确实介绍了 UI 数据绑定。我看了很多帖子和 doco,似乎有很多不同的使用 ViewModel 的方法,所以有点混乱。
在我的主要 activity 中,我有以下...
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initialise()
}
private fun initialise() {
try {
val factory = InjectorUtils.provideViewModelFactory()
val viewModel = ViewModelProvider(this, factory).get(MainActivityViewModel::class.java)
viewModel.mode.observe(this, Observer<Int> { mode ->
// Update
});
} catch (ex: Exception) {
val m = ex.message;
}
}
并且 ViewModel 包含
package com.example.myApp
import androidx.databinding.Bindable
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.example.myApp.Modes
// View model to hold all UI state
class MainActivityViewModel(private val repository: Repository): ViewModel() {
val mode: MutableLiveData<Int> = MutableLiveData<Int>(0)
val stopColour: MutableLiveData<String> = MutableLiveData<String>("hello")
init{
mode.value = Modes.AUTO_MIDI
stopColour.value = "123"
}
}
布局中声明了变量...
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="viewModel"
type="com.example.myapp.MainActivityViewModel" />
</data>
<GridLayout
...
<RadioButton
android:textColor="#FCFFFEFE"
android:id="@+id/radioButtonAuto"
android:layout_gravity="fill_horizontal"
android:layout_row="1"
android:layout_column="0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@={viewModel.stopColour}"> <--- my test binding
</RadioButton>
当我在主 activity 中放置一个断点时,我可以看到 ViewModel 已创建,并且其中有值...
没有例外,但是,绑定文本 ("123") 只是没有出现在 UI 中。
我可能在这里遗漏了什么?
您需要使用 DataBindingUtils 将视图绑定到 activity,而不是使用 setContentView。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityMainBinding = DataBindingUtil.setContentView(
this, R.layout.activity_main)
binding.lifecycleOwner = this
binding.viewModel = viewModel [Your viewModel class object]
}
基本上您需要为绑定定义 viewLifecycle 所有者,并为您在 xml 文件中创建的变量定义一个值。
双向数据绑定在像 EditText 这样的情况下很有用。对于单选按钮或 TextView 等,您可以简单地使用绑定。
android:text="@{viewModel.stopColour}"
以上代码片段适用于单选按钮。
有关详细信息,您可以访问下面的 android 开发人员文档 link。
https://developer.android.com/topic/libraries/data-binding
您需要初始化您的视图绑定 viewModel 到您的 activity viewModel 对象
val activityViewModel = ViewModelProvider(this,factory).get(MainActivityViewModel::class.java)
你的观点binding.viewModel = activityViewModel
我正在尝试学习如何使用 MVVM,以及 Android 中的双向数据绑定。我非常熟悉 MVVM 和来自其他 languages/frameworks(.net、Angular 等)
的双向数据绑定所以,据我所知,我想要一个 viewModel 来保留数据,我还想要一个 repository,我将把它传递给服务(例如播放音频文件)
我按照 this tutorial 设置了视图模型,但我确实介绍了 UI 数据绑定。我看了很多帖子和 doco,似乎有很多不同的使用 ViewModel 的方法,所以有点混乱。
在我的主要 activity 中,我有以下...
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initialise()
}
private fun initialise() {
try {
val factory = InjectorUtils.provideViewModelFactory()
val viewModel = ViewModelProvider(this, factory).get(MainActivityViewModel::class.java)
viewModel.mode.observe(this, Observer<Int> { mode ->
// Update
});
} catch (ex: Exception) {
val m = ex.message;
}
}
并且 ViewModel 包含
package com.example.myApp
import androidx.databinding.Bindable
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.example.myApp.Modes
// View model to hold all UI state
class MainActivityViewModel(private val repository: Repository): ViewModel() {
val mode: MutableLiveData<Int> = MutableLiveData<Int>(0)
val stopColour: MutableLiveData<String> = MutableLiveData<String>("hello")
init{
mode.value = Modes.AUTO_MIDI
stopColour.value = "123"
}
}
布局中声明了变量...
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="viewModel"
type="com.example.myapp.MainActivityViewModel" />
</data>
<GridLayout
...
<RadioButton
android:textColor="#FCFFFEFE"
android:id="@+id/radioButtonAuto"
android:layout_gravity="fill_horizontal"
android:layout_row="1"
android:layout_column="0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@={viewModel.stopColour}"> <--- my test binding
</RadioButton>
当我在主 activity 中放置一个断点时,我可以看到 ViewModel 已创建,并且其中有值...
没有例外,但是,绑定文本 ("123") 只是没有出现在 UI 中。
我可能在这里遗漏了什么?
您需要使用 DataBindingUtils 将视图绑定到 activity,而不是使用 setContentView。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityMainBinding = DataBindingUtil.setContentView(
this, R.layout.activity_main)
binding.lifecycleOwner = this
binding.viewModel = viewModel [Your viewModel class object]
}
基本上您需要为绑定定义 viewLifecycle 所有者,并为您在 xml 文件中创建的变量定义一个值。 双向数据绑定在像 EditText 这样的情况下很有用。对于单选按钮或 TextView 等,您可以简单地使用绑定。
android:text="@{viewModel.stopColour}"
以上代码片段适用于单选按钮。 有关详细信息,您可以访问下面的 android 开发人员文档 link。 https://developer.android.com/topic/libraries/data-binding
您需要初始化您的视图绑定 viewModel 到您的 activity viewModel 对象 val activityViewModel = ViewModelProvider(this,factory).get(MainActivityViewModel::class.java)
你的观点binding.viewModel = activityViewModel