Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwipeRefreshLayout from support lib. v21 doesn't work with static content

I'm using SwipeRefreshLayout from Support Library v21. It's work perfectly with scrollable content like List or ScrollView, but is't working with static layout:

<android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/refresh_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:gravity="center"
            android:text="Content"/>
    </ScrollView>
</android.support.v4.widget.SwipeRefreshLayout>

This code works well.

Video: Example

<android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/refresh_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"> 

        <TextView
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:gravity="center"
            android:text="Content"/>
</android.support.v4.widget.SwipeRefreshLayout>

And that is not.

Video: Example

Is it possible to work with non-scrollable content in SwipeRefreshLayout?

like image 574
nbumakov Avatar asked Jan 10 '23 05:01

nbumakov


1 Answers

Update:

This issue has now been fixed in version 24.2.0 of the support library.


Original Answer:

This is a regression in version 21 of the support library, caused by the fact that the drag calculation was removed from the onTouchEvent() callback of SwipeRefreshLayout, and retained only in the onInterceptTouchEvent() callback. Therefore SwipeRefreshLayout works properly only when it intercepts touch events from a (touch consuming) child View. Interestingly, this issue was also present when SwipeRefreshLayout was originally introduced in version 19.1.0 of the support library, but was fixed in version 20.

I have reported this on the issue tracker at https://code.google.com/p/android/issues/detail?id=87789

This can be patched by extending SwipeRefreshLayout and redirecting it's onTouchEvent() callbacks to onInterceptTouchEvent() until it returns true:

public class FixedSwipeRefreshLayout extends SwipeRefreshLayout {
    public FixedSwipeRefreshLayout(Context context) {
        super(context);
    }

    public FixedSwipeRefreshLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    private boolean handleTouch = true;
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int action = MotionEventCompat.getActionMasked(ev);
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                handleTouch = false;
                break;
            default:
                if (handleTouch) {
                    return super.onTouchEvent(ev);
                }
                handleTouch = onInterceptTouchEvent(ev);
                switch (action) {
                    case MotionEvent.ACTION_UP:
                    case MotionEvent.ACTION_CANCEL:
                        handleTouch = true;
                        break;
                }
                break;
        }
        return true;
    }
}
like image 200
corsair992 Avatar answered Jan 31 '23 19:01

corsair992