Đây là giải pháp tối thượng. Chỉ cần đặt lớp này trong dự án của bạn.
@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();
}
}
Đồng thời thêm tài nguyên id vào tài nguyên của bạn.
<resources>
<item name="page_change_listener" type="id"/>
</resources>
Sau đó, bạn sẽ có thể sử dụng nó trong xml như:
<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}"/>
Như bạn thấy, currentPage
đã nghịch đảo ràng buộc, vì vậy ViewModel của bạn sẽ có thể thiết lập trang hiện tại và cũng có được hiện tại trang nếu người dùng vuốt.
Giải pháp không tốt. Bởi vì ViewPager thêm OnPageChangeListener vào ArrayList nội bộ, gọi notifyChange() cho thuộc tính này sẽ làm cho nó thêm một vài người nghe. Đã cập nhật – b1n0m
@ b1n0m để xóa người nghe trước khi thêm người nghe –