xrecyclerview有的手机不能加载更多

一、确定问题

首先确定一下问题到底是什么,测试说xrecyclerview(一个github上的三方库,不知道的可以去github上找找,有细节上的bug整体来说很好用)的上拉加载更多功能在有的手机上可以加载更多,有的手机上不能加载更多,这说明这个功能是没有问题的,因为有手机可以实现,难道是手机的问题?拿来测试说的不能上拉加载更多的手机,连上adb,查看一下日志,没有很多信息,就是onLoadMore()接口方法没有被调用,打开crecyclerview源码,找到哪里调用了这个接口,如下:

@Override
    public void onScrollStateChanged(int state) {
        super.onScrollStateChanged(state);
        if (state == RecyclerView.SCROLL_STATE_IDLE && mLoadingListener != null && !isLoadingData && loadingMoreEnabled) {
            LayoutManager layoutManager = getLayoutManager();
            int lastVisibleItemPosition;
            if (layoutManager instanceof GridLayoutManager) {
                lastVisibleItemPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition();
            } else if (layoutManager instanceof StaggeredGridLayoutManager) {
                int[] into = new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()];
                ((StaggeredGridLayoutManager) layoutManager).findLastVisibleItemPositions(into);
                lastVisibleItemPosition = findMax(into);
            } else {
                lastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
            }
            if (layoutManager.getChildCount() > 0
                    && lastVisibleItemPosition >= layoutManager.getItemCount() - 1 && layoutManager.getItemCount() > layoutManager.getChildCount() && !isNoMore && mRefreshHeader.getState() < ArrowRefreshHeader.STATE_REFRESHING) {
                isLoadingData = true;
                if (mFootView instanceof LoadingMoreFooter) {
                    ((LoadingMoreFooter) mFootView).setState(LoadingMoreFooter.STATE_LOADING);
                } else {
                    mFootView.setVisibility(View.VISIBLE);
                }
                mLoadingListener.onLoadMore();
            }
        }
    }

通过源码可以看出来,那个一长串的条件就是影响上拉加载更多接口onLoadMore能不能被调用的关键。
那么现在确定了影响条件的关键,下一步就是想办法筛选这些条件,看看到底是谁影响了代码。

二、确定影响条件

因为是使用依赖下载的三方库,所以并不能直接修改源码,或者打印断点调试,从github上下载源码运行编译的时间又比较长,所以我选择了一个比较懒的方法,写一个TestXRecyclerview继承xrecyclerview,并重写onScrollStateChanged(int state)方法,让他运行我自己的方法,这里需要注意的是,一般情况下,还是用下载源码打断点调试的方法比较好,但是这个问题涉及到的类和方法只有一个,所以用了这样的方式。
具体TestXRecyclerview类代码如下:

public class TestXRecyclerView extends XRecyclerView {

    public TestXRecyclerView(Context context) {
        super(context);
    }

    public TestXRecyclerView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public TestXRecyclerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public void onScrollStateChanged(int state) {
//        super.onScrollStateChanged(state);
        if (state == RecyclerView.SCROLL_STATE_IDLE) {
            Log.i("log" , "==是否调用加载更多方法1==");
            LayoutManager layoutManager = getLayoutManager();
            int lastVisibleItemPosition;
            if (layoutManager instanceof GridLayoutManager) {
                lastVisibleItemPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition();
            } else if (layoutManager instanceof StaggeredGridLayoutManager) {
                int[] into = new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()];
                ((StaggeredGridLayoutManager) layoutManager).findLastVisibleItemPositions(into);
                lastVisibleItemPosition = 20;
            } else {
                lastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
            }
            if (layoutManager.getChildCount() > 0
                    && lastVisibleItemPosition >= layoutManager.getItemCount() - 1 && layoutManager.getItemCount() > layoutManager.getChildCount()) {
                Log.i("log" , "==是否调用加载更多方法2==");
            }
        }
    }
}

首先是把super.onScrollStateChanged(state);方法注释掉,然后复制源码里面的onScrollStateChanged(int state) 方法出来,把一些无关的条件去掉(这里需要自己判断是否有关),最终剩下以上代码,运行,并没有调用自己写的log:方法2,说明layoutManager.getChildCount() > 0 , lastVisibleItemPosition >= layoutManager.getItemCount() - 1 , layoutManager.getItemCount() > layoutManager.getChildCount() 这三个条件中有一个或者几个返回了false。这里先看layoutManager.getChildCount() > 0,这个条件肯定不是false,因为数据都显示出来了,那就是剩下的两个条件,其实到这里我已经突然想到了,有可能是item的总高度不够导致上拉加载更多不能触发,因为我们分页机制是一页返回十条,现在一页里面已经显示了九条多的数据,不同手机的高度不一样,这就是为什么有的手机可以有的手机不可以,不过既然已经到了这里,还是要完整的解决问题才行
想解决上面的问题,就要明白layoutManager.getItemCount()和 layoutManager.getChildCount()是什么意思,顺手开始谷歌,感觉不对,说好的看源码呢?于是回去,ctrl点开getChildCount()方法源码

/**
         * Return the current number of child views attached to the parent RecyclerView.
         * This does not include child views that were temporarily detached and/or scrapped.
         *
         * @return Number of attached children
         */
        public int getChildCount() {
            return mChildHelper != null ? mChildHelper.getChildCount() : 0;
        }

嗯。。。再点开mChildHelper.getChildCount()

int getChildCount() {
        return mCallback.getChildCount() - mHiddenViews.size();
    }

看英文意思,应该是所有item的数量,减去没有显示在页面上的item的数量,那getChildCount()就是显示在页面上的item的数量咯。那不出意外,layoutManager.getItemCount()应该就是所有item的数量,很好,我已经提起兴趣了,点开源码:

public int getItemCount() {
            final Adapter a = mRecyclerView != null ? mRecyclerView.getAdapter() : null;
            return a != null ? a.getItemCount() : 0;
        }

猜对啦,现在基本上能明白,lastVisibleItemPosition >= layoutManager.getItemCount() - 1,layoutManager.getItemCount() > layoutManager.getChildCount() ,这两句话都是同一个意思能看到的item数量,要比所有的item的数量大,不然就不触发上拉加载更多,想一想,分页返回十条数据,一页就显示了九条,在不同手机上因为分辨率的不同,有的能看到九条,有的能看到十条,找到了原因所在,问题就很好解决了,给item增加一些高度,或者让后台每条数据返回多一些就可以啦。



作者:Zero零夜
链接:https://www.jianshu.com/p/8fe3af6890f2
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

猜你喜欢

转载自blog.csdn.net/qijingwang/article/details/79909120
今日推荐