CommonPullToRefresh:SwipeRefreshLayout嵌套RecyclerView,配合SwipeRefreshHelper 加载更多报错 解决方案

CommonPullToRefresh是一个开源的支持上拉刷新下拉加载更多的控件的库

附上原作者介绍:

android-Ultra-Pull-To-Refresh的基础上增加了加载更多的支持,感谢作者

  • 下拉刷新支持大部分viewListViewScrollViewWebView等,甚至一个单独的TextView
  • 加载更多目前支持ListViewRecyclerViewGridViewSwipeRefreshLayout
  • 支持自定义header以及footer
  • 增加SwipeRefreshLayout刷新方式,同样支持加载更多

github地址:https://github.com/Chanven/CommonPullToRefresh

但是在SwipeRefreshLayout嵌套RecyclerView,配合SwipeRefreshHelper使用的时候编译版本太高(本人测试时27的)会报异常:IllegalStateException :unSupported contentView

定位发现是SwipeRefreshHelper里的

setLoadMoreEnable()

方法里抛的异常:

if (null == mLoadMoreHandler) {
                if (mContentView instanceof GridView) {
                    mLoadMoreHandler = new GridViewHandler();
                } else if (mContentView instanceof AbsListView) {
                    mLoadMoreHandler = new ListViewHandler();
                } else if (mContentView instanceof RecyclerView) {
                    mLoadMoreHandler = new RecyclerViewHandler();
                } 
            }

            if (null == mLoadMoreHandler) {
                throw new IllegalStateException("unSupported contentView !");
            }

这就很纠结了,我的mContentView 是Recyclerview没错,为什么mLoadMoreHandler还是null呢??

原因在SwipeRefreshHelper的构造函数里:

public SwipeRefreshHelper(SwipeRefreshLayout refreshLayout) {
        this.mSwipeRefreshLayout = refreshLayout;
        init();
    }

继续点进init()方法里:

private void init() {
        if (mSwipeRefreshLayout.getChildCount() <= 0) {
            throw new RuntimeException("SwipRefreshLayout has no child view");
        }
        try {
            Field field = mSwipeRefreshLayout.getClass().getDeclaredField("mTarget");
            field.setAccessible(true);
            mContentView = (View) field.get(mSwipeRefreshLayout);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
实际上,这里
Field field = mSwipeRefreshLayout.getClass().getDeclaredField("mTarget");

反射获取并没有获取到SwipeRefreshLayout里的私有变量mTarget,具体原因可以查看SwipeRefreshLayout的源码,

解决方案:

重写下init方法:

private void init() {
        if (mSwipeRefreshLayout.getChildCount() <= 0) {
            throw new RuntimeException("SwipRefreshLayout has no child view");
        }
        mSwipeRefreshLayout.post(() -> {
            try {
                Field field = mSwipeRefreshLayout.getClass().getDeclaredField("mTarget");
                field.setAccessible(true);
                mContentView = (View) field.get(mSwipeRefreshLayout);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }
即让此view所有的工作都做完后再发消息,获取其变量,这样做就ok了。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
基于SwipeRefreshLayout下拉刷新、上拉加载。支持所有的AbsListView、RecycleView 特点  在 layout 中使用,支持 AbsListView 所有的xml属性  支持自动下拉刷新,什么用呢?比如进入界面时,只需要调用 autoRefresh() 方法即可,同时下拉刷新回调函数将会被调用。  上拉加载支持自定义 View 或设置加载文字、动画  轻松设置 Adapter 空数据视图,默认为 TextView 支持更文字,也可自定义 View  对于简单的界面,如只有 ListView 可以继承 app 包中 Fragment 轻松搞定 效果图 使用 仔细看 listSelector 属性,效果见 sample <com.mylhyl.prlayout.SwipeRefreshListView xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://schemas.android.com/tools"     android:id="@ id/swipeRefresh"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:listSelector="@drawable/selector_list"     tools:context=".app.ListViewXmlFragment" /> 设置上拉加载更多方法见 IFooterLayout         IFooterLayout footerLayout = swipeRefreshListView.getFooterLayout();         footerLayout.setFooterText("set自定义加载");         footerLayout.setIndeterminateDrawable(getResources().getDrawable(R.drawable.footer_progressbar)); 自定义adapter空数据视图         ImageView emptyView = new ImageView(getContext());         emptyView.setImageResource(R.mipmap.empty);         swipeRefreshGridView.setEmptyView(emptyView); 或         swipeRefreshListView.setEmptyText("数据呢?"); 使用Gradle构建时添加一下依赖即可: compile 'com.mylhyl:pullrefreshlayout:1.0.0' QQ交流群:435173211

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值