SwipeRefreshLayout and Vertical ViewPager Touch Issues

1.4k views Asked by At

I have a Activity with Custom SwipeRefreshLayout and a Vertical ViewPager which swipes vertically. (basically a deck of cards which can be refershed by using swipe to refresh).

So Now when i try to swipe the Vertical Viewpager SwipeRefreshLayout handles the touch event and refresh the layout and the view pager's page does't move.

Two things i tried but with no luck:

  1. Enable swipe to refresh layout only when user starts from the toolbar. MotionEvent.ACTION_DOWN event getY() gives toolbar's y coordinate.

  2. If the ViewPager is the first to accept the touch event then
    don't delegate it to SwipeRefreshLayout.

The Layout file of the activity looks like this.

<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:HelveticaTextView="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:fab="http://schemas.android.com/apk/res-auto"
android:id="@+id/DrawerLayout" android:layout_width="match_parent"
android:layout_height="match_parent">


<com.CustomSwipeToRefresh xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/swipe_container" android:layout_width="match_parent"
    android:layout_height="100dp" app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <android.support.design.widget.CoordinatorLayout
        android:id="@+id/coordinatorLayout" android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.Toolbar
            android:id="@+id/tool_bar" android:layout_width="match_parent"
            android:layout_height="@dimen/toolbar_min_height"
            android:background="@color/theme_color_yellow_dark"
            app:layout_collapseMode="pin"
            app:layout_scrollFlags="scroll|enterAlways" app:titleTextColor="@color/white">

        </android.support.v7.widget.Toolbar>


        <RelativeLayout android:layout_width="match_parent"
            android:layout_height="match_parent" android:layout_marginBottom="@dimen/toolbar_min_height"
            android:layout_marginTop="@dimen/toolbar_min_height"
            android:background="@color/transparent">

            <com.VerticalViewPager 
                android:id="@+id/pagerhome"
                android:layout_width="match_parent" 
                android:layout_height="match_parent" />

        </RelativeLayout>

    </android.support.design.widget.CoordinatorLayout>

</com.CustomSwipeToRefresh>

<!-- to show nav drawer icons here -->
<android.support.v7.widget.RecyclerView
    android:id="@+id/RecyclerView" android:layout_width="320dp"
    android:layout_height="match_parent" android:layout_gravity="left"
    android:background="#ffffff" android:scrollbars="vertical">

  </android.support.v7.widget.RecyclerView>


</android.support.v4.widget.DrawerLayout>

My CustomSwipeToRefresh touch intercept action which doesnot work well

 @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:

                mPrevY = MotionEvent.obtain(event).getY();
                mDeclined = false; // New action
                break;

            case MotionEvent.ACTION_MOVE:


                final float eventY = event.getY();
                float yDiff = Math.abs(eventY - mPrevY);

                //disable swipe to refresh if user touches below 100px or dp
                if (mDeclined || mPrevY > 100  ) {
                    mDeclined = true; 
                    return false;
                }
        }

        return super.onInterceptTouchEvent(event);
    }
2

There are 2 answers

0
Santosh Joshi On BEST ANSWER

The below logic worked for me

Enable swipe to refresh layout when user starts dragging from the toolbar. i.e if the user tries to swipe from very top and it includes the toolbar then only enable swipe and if user touch start after toolbar position then disable swipe enter image description here

@Override
    public boolean onInterceptTouchEvent(MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mPrevY = MotionEvent.obtain(event).getY();
                mDeclined = false; 

                if (mPrevY > getResources().getDimensionPixelSize(R.dimen.disable_swipe_after) ) {
                    mDeclined = true; 
                }
                Log.d("Declined", mDeclined + "--" + mPrevY);

                break;

            case MotionEvent.ACTION_MOVE:

                if (mDeclined) {
                    return false;
                }
        }
        return super.onInterceptTouchEvent(event);
    }
0
Ashish Pandey On
mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        Log.e("onPageScrolled position(=",String.valueOf(position));
        Log.e("onPageScrolled positionOffset(=",String.valueOf(positionOffset));
        Log.e("onPageScrolled positionOffsetPixels(=",String.valueOf(positionOffsetPixels));
    }

    @Override
    public void onPageSelected(int position) {
        Log.e("onPageSelected position(=",String.valueOf(position));
    }

    @Override
    public void onPageScrollStateChanged(int state) {
        Log.e("onPageScrollStateChanged state(=",String.valueOf(state));
        if(state==1) {
            swipeRefreshLayout.setEnabled(false);
        } else {
           swipeRefreshLayout.setEnabled(true);
        }
    }
});