I want to change the live data of the view model and output it to the view. I set the string as the initial value, and after that, I try to change the string by executing a function in the view model, but it does not change. Is there something wrong??
ViewModel.kt
class MainViewModel: ViewModel() {
private var _title_1 = MutableLiveData<String>()
init {
_title_1.value = "PISO NOBLE"
}
val title_1: MutableLiveData<String>
get() = _title_1
fun changeCat () {
_title_1.value = "PISO NOBRE" }
fragement_page.xml
<TextView
android:id="@+id/pageOneTitle_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textSize="24dp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/langCat"
android:layout_width="160dp"
android:layout_height="match_parent"
style="@style/Widget.MaterialComponents.ExtendedFloatingActionButton"
app:cornerRadius="28dp"
android:onClick="@{()->mainViewModel.changeCat()}"
android:text="CAT"
android:textSize="24dp" />
PageFragement.kt
class PageOne : Fragment() {
private var _binding: FragmentPageOneBinding? = null
private val binding get() = _binding!!
private val mainViewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentPageOneBinding.inflate(inflater, container, false)
mainViewModel.title_1.observe(viewLifecycleOwner, Observer {
binding.pageOneTitle1.text = it.toString()
})
val view = binding.root
val vFlipper: ViewFlipper = binding.viewFlipper as ViewFlipper
return view
}
>Solution :
Is there something wrong??
My first guess is that you didn’t set the viewmodel on the binding. You have:
app:cornerRadius="28dp"
android:onClick="@{()->mainViewModel.changeCat()}"
android:text="CAT"
Which implies you have a variable in the layout named mainViewModel. So you should set that on the binding. And since you’re using LiveData you should set the LifeCycleOwner as well.
_binding = FragmentPageOneBinding.inflate(inflater, container, false)
// v--- MISSING THIS -------
_binding.setMainViewModel(mainViewModel) // <- Set the variable
_binding.setLifeCycleOwner(this) // <- Also need this to observe LiveData
// ^--- MISSING THIS -------
mainViewModel.title_1.observe(viewLifecycleOwner, Observer {
binding.pageOneTitle1.text = it.toString()
})
val view = binding.root
val vFlipper: ViewFlipper = binding.viewFlipper as ViewFlipper
return view
This is all covered in the documentation for databinding.