Hier ist die ultimative Lösung. Fügen Sie diese Klasse einfach in Ihr Projekt ein.
@BindingMethods({
@BindingMethod(type = ViewPager.class, attribute = "android:offscreenPageLimit", method = "setOffscreenPageLimit"),
@BindingMethod(type = ViewPager.class, attribute = "android:adapter", method = "setAdapter"),
@BindingMethod(type = ViewPager.class, attribute = "android:currentPage", method = "setCurrentItem"),
})
public final class ViewPagerBindingAdapter {
@InverseBindingAdapter(attribute = "android:currentPage", event = "android:currentPageAttrChanged")
public static int getCurrentPage(@NonNull final ViewPager pager) {
return pager.getCurrentItem();
}
@BindingAdapter(value = {"android:onPageScrolled", "android:onPageSelected", "android:onPageScrollStateChanged",
"android:currentPageAttrChanged"}, requireAll = false)
public static void onSetAdapter(@NonNull final ViewPager pager, final OnPageScrolled scrolled, final OnPageSelected selected,
final OnPageScrollStateChanged scrollStateChanged, final InverseBindingListener currentPageAttrChanged) {
final ViewPager.OnPageChangeListener newValue;
if (scrolled == null && selected == null && scrollStateChanged == null && currentPageAttrChanged == null) {
newValue = null;
} else {
newValue = new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {
if (scrolled != null) {
scrolled.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
@Override
public void onPageSelected(final int position) {
if (selected != null) {
selected.onPageSelected(position);
}
if (currentPageAttrChanged != null) {
currentPageAttrChanged.onChange();
}
}
@Override
public void onPageScrollStateChanged(final int state) {
if (scrollStateChanged != null) {
scrollStateChanged.onPageScrollStateChanged(state);
}
}
};
}
final ViewPager.OnPageChangeListener oldValue = ListenerUtil.trackListener(pager, newValue, R.id.page_change_listener);
if (oldValue != null) {
pager.removeOnPageChangeListener(oldValue);
}
if (newValue != null) {
pager.addOnPageChangeListener(newValue);
}
}
public interface OnPageScrolled {
void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);
}
public interface OnPageSelected {
void onPageSelected(int position);
}
public interface OnPageScrollStateChanged {
void onPageScrollStateChanged(int state);
}
private ViewPagerBindingAdapter() {
throw new UnsupportedOperationException();
}
}
Fügen Sie auch ID-Ressource in Ihren Ressourcen hinzu.
<resources>
<item name="page_change_listener" type="id"/>
</resources>
Dann werden Sie in der Lage sein, es in XML zu verwenden wie:
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="match_parent"
android:currentPage="@={viewModel.currentPage}"
android:offscreenPageLimit="@{viewModel.offscreenPageLimit}"
android:onPageSelected="@{currentPage -> viewModel.pageSelected(currentPage)}"
android:adapter="@{adapter}"/>
Wie Sie sehen können, currentPage
inverse Bindung hat, so dass Ihr Ansichtsmodell wird in der Lage sein, aktuelle Seite zu setzen und auch Strom bekommen Seite, wenn der Benutzer wischt.
Nicht gute Lösung. Da ViewPager OnPageChangeListener zur internen ArrayList hinzufügt, wird durch den Aufruf von notifyChange() für diese Eigenschaft das Hinzufügen mehrerer Listener erfolgen. – b1n0m
@ b1n0m aktualisiert, um Listener zuerst zu entfernen, bevor Listener hinzugefügt werden –