(4.0.28.1)SwipeRefreshLayout 自定义 canChildScrollUp

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();
    }

 

 

文/substarry(简书作者)
原文链接:http://www.jianshu.com/p/ddb91b14c36f
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值