Search code examples
androiddata-binding

How to execute method onClick?


Recently started working with databinding. There was a problem. The onClick method sometimes works, sometimes it doesn't. Tried a lot of solutions, but they don't help. When i click on layout, nothing happens.

Code in activity.

private lateinit var viewModel: ProfileViewModel
private lateinit var binding: ActivityProfileBinding
override fun onCreate(savedInstanceState: Bundle?)
{
    super.onCreate(savedInstanceState)
    viewModel = ViewModelProviders.of(this).get(ProfileViewModel::class.java)
    viewModel.supportFragmentManager = supportFragmentManager
    binding = DataBindingUtil.setContentView(this, R.layout.activity_profile)
    binding.apply {
        binding.viewModel = viewModel
        binding.executePendingBindings()
    }
}

Code in XML.

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
<data>
    <variable name="viewModel" type="com.example.testcoursework.viewModel.ProfileViewModel"/>
</data>
<LinearLayout
        android:orientation="vertical"
        android:background="@color/grey"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".ui.activity.ProfileActivity">
    <RelativeLayout
            android:clickable="true"
            android:focusable="true"
            android:onClick="@{() -> viewModel.changeGender()}" ...>
        <ImageView .../>
        <TextView .../>
        <TextView .../>
    </RelativeLayout>
</LinearLayout>
</layout>

Code in ViewModel.

fun changeGender()
{
    Log.d(LOG_TAG, "Click")
    val dialog = ChangeGenderDialog()
    dialog.show(supportFragmentManager, "ChangeGender")
}

Tried to rewrite the method like this

android:onClick="@{viewModel::changeGender()}

It's doesn't work. Set listener from code also doesn't work.


Solution

  • Either directly assign viewModel to binding adapter like below:

    binding.viewModel = viewModel
    binding.executePendingBindings()
    

    or rename viewModel to profileViewModel and assign inside apply.

    private lateinit var profileViewModel: ProfileViewModel
    
    override fun onCreate(savedInstanceState: Bundle?)
    {
        super.onCreate(savedInstanceState)
        profileViewModel = ViewModelProviders.of(this).get(ProfileViewModel::class.java)
        profileViewModel.supportFragmentManager = supportFragmentManager
        binding = DataBindingUtil.setContentView(this, R.layout.activity_profile)
    
        binding.apply {
            viewModel = profileViewModel
            executePendingBindings()
        }
    }
    

    Actually inside apply you assign binding variable viewModel to itself. That's why it's not working.