Android Data Binding pass arguments to onClick method

JavaAndroidXmlData Binding

Java Problem Overview


Is it possible to pass custom arguments to onClick method using the Data Binding Library? I have my layout xml file where I need to use the onClickListener:

<?xml version="1.0" encoding="utf-8"?>
<layout ...>

    <data>
        <variable
            name="viewModel"
            type="com.productivity.tiktak.ui.tracker.viewModel.CategoryViewModel"/>
        <variable
            name="callback"
            type="com.productivity.tiktak.ui.tracker.TrackerAdapter"/>
    </data>

    <android.support.v7.widget.CardView
        android:onClick="@{callback.onCategoryClick(viewModel)}"
        ...
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

       <!-- ... Some stuff -->
        
    </android.support.v7.widget.CardView>
</layout>

and I a have my click handler code here:

public void onCategoryClick(View view, CategoryViewModel categoryViewModel)
{
    //handler code...
}

Is it possible to pass my CategoryViewModel object from xml to click handler?

Java Solutions


Solution 1 - Java

You can use a lambda expressions and pass the view in as a parameter.

 android:onClick="@{() -> callback.onCategoryClick(viewModel)}"

If you need the view, you can pass that as well with:

 android:onClick="@{(view) -> callback.onCategoryClick(view, viewModel)}"

Solution 2 - Java

Multiple Ways:
Solution 1 (When you have Presenter)

You have a presenter or handler class like below

public class Presenter {
    public void onSaveClick(View view, Task task){}
}

Now take variable of type Presenter in your layout. and set click like below.

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="task" type="com.android.example.Task" />
        <variable name="presenter" type="com.android.example.Presenter" />
    </data>
    <LinearLayout ...>
        <Button 
           android:layout_width="wrap_content" 
           android:layout_height="wrap_content"
           android:onClick="@{(view) -> presenter.onSaveClick(view, task)}"
           />
    </LinearLayout>
</layout>

You can add any more arguments in this.

Please note that, you have to set these data variables in the onCreate() method. Like below

ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setTask(task);
binding.setPresenter(presenter);
Solution 2 (When you don't have Presenter)

Create a variable type of your Activity / Fragment

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="task" type="com.android.example.Task" />
        <variable name="activity" type="com.example.MainActivity" />
    </data>
    <LinearLayout ...>
        <Button 
           android:layout_width="wrap_content" 
           android:layout_height="wrap_content"
           android:onClick="@{(view) -> activity.onSaveClick(view, task)}"
           />
    </LinearLayout>
</layout>

and make method in your activity which you want to call from binding layout. and don't forget to call setActivity(YourActivity.this) from Activity.

public class MainActivity extends AppCompatActivity {
    public void onSaveClick(View view, Task task) {
        System.out.println("MainActivity.onSaveClick");
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        binding.setActivity(this);
        binding.setTask(task);
    }
}

Further reading Android DataBinding documentation

There are many other ways to set click, check this answer.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionkolodachView Question on Stackoverflow
Solution 1 - JavayigitView Answer on Stackoverflow
Solution 2 - JavaKhemraj SharmaView Answer on Stackoverflow