4

我正在使用 Support Library v21 中的 SwipeRefreshLayout。它适用于 List 或 ScrollView 等可滚动内容,但不适用于静态布局:

<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>

这段代码运行良好。

视频:示例

<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>

事实并非如此。

视频:示例

是否可以在 SwipeRefreshLayout 中使用不可滚动的内容?

4

1 回答 1

9

更新:

此问题现已在支持库的版本 24.2.0 中得到修复。


原答案:

这是支持库版本 21 中的回归,原因是拖动计算已从onTouchEvent()回调中删除SwipeRefreshLayout,并且仅保留在onInterceptTouchEvent()回调中。因此SwipeRefreshLayout,仅当它拦截来自(触摸消耗)子级的触摸事件时才能正常工作View。有趣的是,这个问题SwipeRefreshLayout最初在支持库的 19.1.0 版本中引入时也存在,但在版本 20 中得到了修复。

我已在https://code.google.com/p/android/issues/detail?id=87789的问题跟踪器上报告了这一点

这可以通过扩展SwipeRefreshLayout和重定向它的onTouchEvent()回调来修补,onInterceptTouchEvent()直到它返回 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;
    }
}
于 2014-12-24T04:25:25.093 回答