一席Android

SwipeRefreshLayout 自定义 canChildS

2016-05-25  本文已影响1531人  substarry

SwipeRefreshLayout 是一个下拉属性控件,只需要将如ListView、RecyclerView等控件作为它的child view即可,它可以自己处理下拉事件,当child view可以下拉时,则优先滑动child view,当child view滑到顶部时,则触发SwipeRefreshLayout 的下拉刷新。

但是当SwipeRefreshLayout 中包含多个child view时,则可能会失效,原因是SwipeRefreshLayout只会通过child view 中最上面的一个view来处理滑动事件。具体看源码:

    public boolean canChildScrollUp() {
        if (android.os.Build.VERSION.SDK_INT < 14) {
            if (mTarget instanceof AbsListView) {
                final AbsListView absListView = (AbsListView) mTarget;
                return absListView.getChildCount() > 0
                        && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0)
                                .getTop() < absListView.getPaddingTop());
            } else {
                return ViewCompat.canScrollVertically(mTarget, -1) || mTarget.getScrollY() > 0;
            }
        } else {
            return ViewCompat.canScrollVertically(mTarget, -1);
        }
    }

可以看到,SwipeRefreshLayout 是优先 mTraget 处理下拉事件的;那么 mTraget哪里定义的呢?

    private void ensureTarget() {
        // Don't bother getting the parent height if the parent hasn't been laid
        // out yet.
        if (mTarget == null) {
            for (int i = 0; i < getChildCount(); i++) {
                View child = getChildAt(i);
                if (!child.equals(mCircleView)) {
                    mTarget = child;
                    break;
                }
            }
        }
    }

从上面的代码可以发现,其实mTraget就是我们放到child view中的第一个View。所以如果我们child view中需要滑动的并不是第一个,那么就会滑动失效,解决方法就是自定一个View继承SwipeRefreshLayout ,同时重写 canChildScrollUp 方法即可。直接上代码:

    //实际需要滑动的child view
    private View mScrollUpChild;
    
    public void setScrollUpChild(View view) {
        mScrollUpChild = view;
    }

    @Override 
    public boolean canChildScrollUp() {
        if (mScrollUpChild != null) {
            if (android.os.Build.VERSION.SDK_INT < 14) {
                if (mScrollUpChild instanceof AbsListView) {
                    final AbsListView absListView = (AbsListView) mScrollUpChild;
                    return absListView.getChildCount() > 0
                            && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0)
                            .getTop() < absListView.getPaddingTop());
                } else {
                    return ViewCompat.canScrollVertically(mScrollUpChild, -1) || mScrollUpChild.getScrollY() > 0;
                }
            } else {
                return ViewCompat.canScrollVertically(mScrollUpChild, -1);
            }
        }
        return super.canChildScrollUp();
    }
上一篇 下一篇

猜你喜欢

热点阅读