DialogFragment with view model not working with data binding

Viewed 1849

I've created one dialog fragemnt with view model (mvvm). Dialog consist of one button (custom view). when using view model with data binding, button click is not working when livedata change.I'm using boolean value to check if button is clicked or not. What is causing issue? Also suggest any other approach if needed.

profile_dialog_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="viewmodel"
            type="com.test.ui.ProfileDialogViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".ui.ProfileDialog">

        <com.google.android.material.button.MaterialButton
            android:id="@+id/login"
            style="@style/TextAppearance.MaterialComponents.Button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Login"
            android:onClick="@{() -> viewmodel.onLoginButtonClick()}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</layout>

ProfileDialog.kt

class ProfileDialog : DialogFragment() {

    companion object {
        fun newInstance() = ProfileDialog()
    }

    private val viewModel: ProfileDialogViewModel by viewModel()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val binding = ProfileDialogFragmentBinding.inflate(inflater, container, false)
            .apply {
                this.lifecycleOwner = this@ProfileDialog
                this.viewmodel = viewmodel
            }
        return binding.root
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        viewModel.startLogin.observe(viewLifecycleOwner, Observer {

            Log.d("insta", "This is working")
            if (it == null) return@Observer

            if(it) {
                Log.d("insta", "This is not working")
                val loginIntent = Intent(this.context, LoginActivity::class.java)
                this.context?.startActivity(loginIntent)
            }
        })
    }

}

ProfileDialogViewModel.kt

class ProfileDialogViewModel : ViewModel() {

    private val _startLogin = MutableLiveData<Boolean>(false)

    val startLogin: LiveData<Boolean>
        get() = _startLogin

    fun onLoginButtonClick() {
        Log.d("insta", "This ain't working")
        _startLogin.postValue(true)
    }
}
1 Answers

Your viewmodel is defined in

private val viewModel: ProfileDialogViewModel by viewModel()

So, pay attention to viewModel. The problem located in

this.viewmodel = viewmodel

where this points to ProfileDialogFragmentBinding. Here you assinging ProfileDialogFragmentBinding.viewmodel = ProfileDialogFragmentBinding.viewmodel - that's why it's not working.

To solve problem, properly assign it like that:

this.viewmodel = viewModel
Related