Is it possible to bind a handler for setOnPageChangeListener to a ViewPager in XML file with the Android Binding functionality?
The demos show onClick events but I am curious as to how much event functionality I can implement with it. Any links on the capabilities of Data Binding would be great as well. Thanks.
Hypothetical example:
example_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="handlers" type="com.example.Handlers"/>
</data>
<android.support.v4.view.ViewPager
android:id="@+id/pager"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:onPageChangeListener="@{handlers.pageChanged}" />
</layout>
Handler.java
package com.example.viewmodels;
import android.view.View;
public class Handlers {
public void pageChanged(View view){}
}
The compilation error is:
Error:(62) No resource identifier found for attribute 'onPageChangeListener' in package 'android'
Stay organized with collections Save and categorize content based on your preferences. The @={} notation, which importantly includes the "=" sign, receives data changes to the property and listen to user updates at the same time.
Layout Binding expressions Expressions in the XML layout files are assigned to a value of the attribute properties using the “ @{} " syntax. We just need to use the basic syntax @{} in an assignment expression.
To enable view binding, configure viewBinding in your module-level build. gradle file. Once enabled for a project, view binding will generate a binding class for all of your layouts automatically. You don't have to make changes to your XML — it'll automatically work with your existing layouts.
It is possible to do this. You need to implement a custom binding adapter because there is no BindingAdapter classes predefined for View classes from Android support libraries.
For how to implement the custom adapter you may read this.
The code should be something like the below, I haven't tested them thoroughly:
<android.support.v4.view.ViewPager
android:id="@+id/pager"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:onPageChangeListener="@{handlers}" />
Your BindingAapter code:
@BindingAdapter("onPageChangeListener")
public static void setOnPageChangeListener(ViewPager viewPager, ViewPager.OnPageChangeListener listener) {
Log.i("setOnPageChangeListener");
// clear listeners first avoid adding duplicate listener upon calling notify update related code
viewPager.clearOnPageChangeListeners();
viewPager.addOnPageChangeListener(listener);
}
P.S. Your handler class being passed should implement ViewPager.OnPageChangeListener
.
Instead of OnPageChangeListener
, you can use SimpleOnPageChangeListener
and only override the method you're interested in:
@BindingAdapter("onPageChanged")
@JvmStatic
fun addPageChangedListener(viewPager: ViewPager, listener: OnPageChanged) {
viewPager.addOnPageChangeListener(object : ViewPager.SimpleOnPageChangeListener() {
override fun onPageSelected(position: Int) {
listener.onPageChanged(position)
}
})
}
interface OnPageChanged {
fun onPageChanged(position: Int)
}
Layout:
<androidx.viewpager.widget.ViewPager
app:onPageChanged="@{viewModel::handlePageChanged}">
Handler:
fun handlePageChanged(position: Int) {
println("Page changed: $position")
}
As others have pointed out, you may want to be careful not to attach duplicate listeners.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With