Using data binding, you can also handle events right from the layout xml using either Method references, or Listener bindings.
For this we can create a seperate Class named “MyHandler”.
Event Handler Class
MyHandler.java
package binding_demo.coderzheaven.com.bindingdemo; import android.util.Log; import android.view.View; import android.widget.Button; import static android.content.ContentValues.TAG; public class MyHandler { public void onClick(View view){ Log.i(TAG, "onClick"); ((Button) view).setText("Clicked"); } }
Like my previous examples you have to initialize the listener in the Activity.
ActivityMainBinding binding = DataBindingUtil. setContentView(this, R.layout.activity_main); binding.setHandler(new MyHandler());
Layout
Now the layout that has a button with the click function in the MyHandler Listener.
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity"> <data> <variable name="handler" type="binding_demo.coderzheaven.com.bindingdemo.MyHandler" /> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/b2" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="@{handler::onClick}" /> </LinearLayout> </layout>
Check the notation in the below line.
android:onClick="@{handler::onClick}"
You can also add the onClick function inside the MainActivity itself.
Then the above code will change like this.
android:onClick="@{onClick}"
Listener Bindings
Listener Bindings are binding expressions that run when an event happens. They are similar to method references, but they let you run arbitrary data binding expressions.
In Listener Bindings, only your return value must match the expected return value of the listener (unless it is expecting void).
Example
public class MyHandler { public void onSaveTask(Task task){} }
The binding in the layout will look like this.
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="task" type="com.coderzheaven.Task" /> <variable name="handler" type="com.coderzheaven.handler" /> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="@{() -> handler.onSaveClick(task)}" /> <!-- This is a void function --> </LinearLayout> </layout>
Then how will the below function look like
public class MyHandler { public void onSaveTask(View view, Task task){} }
The binding in the layout will look like this.
android:onClick="@{(theView) -> handler.onSaveTask(theView, task)}"
Two Parametermethod binding.
public class MyHandler { public void onTaskCompleted(Task task, boolean completed){} }
In Layout
<CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:onCheckedChanged="@{(cb, isChecked) -> handler.onTaskCompleted(task, isChecked)}" />
Binding onLongClick.
public class MyHandler { public boolean onLongClick(View view, Task task){} }
In Layout
android:onLongClick="@{(theView) -> handler.onLongClick(theView, task)}"
Using Predicate in Binding
android:onClick="@{(v) -> v.isVisible() ? doSomething() : void}"
Source Code
You can find the full source code in my GitHub repository.