Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Data Binding pass arguments to onClick method

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?

like image 215
kolodach Avatar asked May 08 '16 21:05

kolodach


2 Answers

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)}"
like image 109
yigit Avatar answered Sep 22 '22 01:09

yigit


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.

like image 25
Khemraj Sharma Avatar answered Sep 24 '22 01:09

Khemraj Sharma