如何分离 TabLayout 和 ViewPager 操作?

How can I separate TabLayout and ViewPager actions?

我在两者之间有一个标准设置,但我希望 TabLayout 的点击(当用户直接触摸 TabLayout 的点时)不同于 ViewPager 的滑动。也许我只想点击操作打印 "tap",滑动操作打印 "swipe"。目前,除了将 TabLayout 附加到 ViewPager 之外,我没有在 TabLayout 上设置任何内容,但是当我在 ViewPager 上滑动时,它会同时打印 "swipe" 和 "tap".

所以花了一些时间,但我终于得到了我想要的。事实证明,TabLayout 的侦听器关心 ViewPager 处理的内容,而不是相反。因此,当 VP 被滑动时,两个听众都听到了。当 TabLayout 被点击时,只有 TabLayout 知道。因此,我可以设置点按功能来执行它的点按操作,然后在滑动功能中我只需确保它可以确定实际移动 VP 的是滑动还是点按。

MVVM 视图模型绑定:

@BindingAdapter({"onAdapterChangeListener"})
public static void setOnAdapterChangeListener(ViewPager viewPager, BehaviorSubject<Void> adapterChangeSubject) {
    viewPager.addOnAdapterChangeListener((viewPager1, oldAdapter, newAdapter) -> adapterChangeSubject.onNext(null));
}

@BindingAdapter({"viewPager","onTap","onSwipe"})
public static void addOnTabSelectedListener(TabLayout tabLayout, ViewPager viewPager, BehaviorSubject<Integer> tapSubject, BehaviorSubject<Integer> swipeSubject) {
    viewPager.addOnAdapterChangeListener((viewPager1, oldAdapter, newAdapter) -> {
        tabLayout.setupWithViewPager(viewPager);
        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                int tabPosition = tab.getPosition();
                if (tabPosition == viewPager.getCurrentItem()) {
                    swipeSubject.onNext(tabPosition);
                    // A swipe will have the VP tell the TabLayout what tab to move to before
                    // this is called, so if the two positions match, it means the user
                    // performed a swipe action
                } else {
                    tapSubject.onNext(tabPosition);
                    viewPager.setCurrentItem(tabPosition);
                    // Otherwise, it was definitely a tap action
                }
            }
            // If I updated from API 23 to 24 I would use tabLayout.addOnTab and wouldn't
            // need these guys below
            @Override
            public void onTabUnselected(TabLayout.Tab tab) {}
            @Override
            public void onTabReselected(TabLayout.Tab tab) {}
        });
    });
}

XML:

<android.support.design.widget.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="-17dp"
        android:layout_gravity="top"
        app:tabBackground="@drawable/dot_tab_selector"
        app:tabGravity="center"
        app:tabIndicatorHeight="0dp"
        app:tabPaddingEnd="5dp"
        app:tabPaddingStart="5dp"
        app:viewPager="@{{viewPager}}"
        app:onTap="@{carouselViewModel.tapSubject}"
        app:onSwipe="@{carouselViewModel.swipeSubject}"/>

    <com.snip.CustomViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clipToPadding="false"
        android:paddingEnd="20dp"
        android:paddingStart="20dp"
        app:onAdapterChangeListener="@{carouselViewModel.carouselAdapterChangeSubject}"/>

CarouselViewModel:

swipeSubject
            .subscribe(page -> {
                doTheSwipeThing();
            });

    tapSubject
            .subscribe(page -> {
                    doTheTapThing();
            });