Android之SwipeRefreshLayout使用和冲突解决

Android之SwipeRefreshLayout使用和冲突解决

文章链接:http://blog.csdn.net/qq_16628781/article/details/64441035

知识点

  1. SwipeRefreshLayout的简介和基本使用;
  2. SwipeRefreshLayout和RecyclerView的冲突解决
  3. 新名词记录{RecyclerView}

概括

SwipeRefreshLayout想必大家已经很熟悉了。在很多主流的APP上面已经有看到一个会变颜色的刷新圈圈。这是SwipeRefreshLayout自带的一个行为。而通常我们使用刷新都会和listview或者RecyclerView一起使用。然而这里会有一个潜在的冲突:当RecyclerView还没有到顶部时,已经触发了SwipeRefreshLayout的刷新动作。

在XML里面的布局如下:

<android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swp_manageOvRefresh"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv_fMvCompanyList"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

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

然后在Java文件里头,我们获取到SwipeRefreshLayout的句柄,然后设置它的下拉的位置、变化的样式、刷新监听等等。


首先是位置设置,setProgressViewOffset()几个参数说明如下
1. 参数1:true,下拉的时候,不会从上面滑动下来,而是在固定的位置缩放出来,缩放回去。
2. 参数2:刷新圈圈出现的位置,单位为像素。
3. 参数3:刷新的圈圈最后定住的位置,单位也是像素。

swipeRefreshLayout.setProgressViewOffset(true, BuildConfig.swipeLayoutStartPointFromTop, BuildConfig.swipeLayoutEndPointFromTop);

然后是刷新滚动时变换的颜色的设置,最多可以设置4种不同的颜色。第一种颜色是默认呈现给用户看到的。在动画的时候,会依次切换不同颜色,直到刷新完成或者取消。
1. 参数1:动画的颜色。
2. 同上。
3. 同上。
4. 同上。

swipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary,
                    R.color.blueLight,
                    R.color.btn_cm_bg_pressed,
                    R.color.withe);

刷新监听,API提供了setOnRefreshListener()方法,只要实现OnRefreshListener接口就可以了。然后在onRefresh()方法里面实现需要的操作。当完成操作之后,调用swipeRefreshLayout.setRefreshing(false)方法取消刷新就可以了。

swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                //加载数据,刷新布局等操作
                //....
                swipeRefreshLayout.setRefreshing(false);
            }
        });

在上面我们看到我们swipeRefreshLayout结合RecyclerView一起使用了。在做项目的时候,大部分的机型是没有什么问题的,但是在一款华为的手机上,就发现了一个问题:滑动冲突了。在往下滑的时候,RecyclerView还没有到达顶部就触发了下拉刷新的动作。这里产生的具体原因未知,得去看源码才知道。

解决方法是,在swipeRefreshLayout类的内部,实现了OnChildScrollUpCallback()方法,这个方法返回值指示swipeRefreshLayout内部的view有没有可能向上滚动,返回true表示可以滚动,返回false表示不可滚动,触发刷新。如果里面的控件是自定义的,就需要重写这个方法。API提供了setOnChildScrollUpCallback()方法给我们重写。如下:

swipeRefreshLayout.setOnChildScrollUpCallback(new SwipeRefreshLayout.OnChildScrollUpCallback() {
            @Override
            public boolean canChildScrollUp(SwipeRefreshLayout parent, @Nullable View child) {
                if (mRecyclerView == null) {
                    return false;
                }
                LinearLayoutManager linearLayoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
                return linearLayoutManager.findFirstCompletelyVisibleItemPosition() != 0;
            }
        });

在这里我们先获得RecyclerView的布局管理器LinearLayoutManager这里使用的是线性布局,还有网格布局GridLayoutManager和瀑布流StaggeredGridLayoutManager布局管理器,可以很方便的实现绚丽的各种界面。

然后findFirstCompletelyVisibleItemPosition()返回的位置是可见区域第一个全部可见的item的位置,这里注意:是整个item全部出现了才算。如果返回的位置不等于0,结果为true,那么swipeRefreshLayout里面的RecyclerView标志为可滚动的,RecyclerView就可以往上滚动。当到了第一个全部item可见的时候,返回的position为0,结果false,那么说明RecyclerView已经到顶了,那么RecyclerView就标志位不可滚动的状态,继续下拉就会触发swipeRefreshLayout的刷新机制了。


总结

以上就是关于swipeRefreshLayout需要注意的一个问题,我的重点是要讲swipeRefreshLayout和RecyclerView之间的冲突,因为我们使用RecyclerView绝大部分的需求都是要自定义item布局的,所以Google也明确的说了,当你是自定义item布局时,必须要重写OnChildScrollUpCallback()方法–原文说明:Override this if the child view is a custom view.

如有任何问题,请及时与我联系,谢谢!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值