XRecyclerviewある携帯電話はもっとロードできません

21965 ワード

一、問題を確定する


まず問題が何なのかを確認し、xrecyclerview(github上の三方ライブラリ、知らないことはgithubで探すことができ、細部のバグがあるのは全体的に使いやすい)のアップロードをテストします.テストでは、より多くの携帯電話をロードすることはできません.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)メソッドを書き直して、自分の方法を実行させます.ここで注意しなければならないのは、一般的には、ソースコードをダウンロードしてデバッグを中断する方法が望ましいが,この問題に関連するクラスと方法は1つしかないので,このような方法を用いた.具体的な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()の3つの条件のうち1つまたは複数がfalseを返します.ここでlayoutManagerを見てみましょうgetChildCount()>0、この条件はfalseではないに違いない.データが表示されているからだ.それは残りの2つの条件だ. , 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;
        }

うん...もっと注文してgetChildCount()
int getChildCount() {
     
        return mCallback.getChildCount() - mHiddenViews.size();
    }

英語の意味を見ると、すべてのitemの数で、ページに表示されていないitemの数を差し引くと、getChildCount()はページに表示されているitemの数ですね.事故じゃないわ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()、この2つの言葉は同じ意味で見えるitemの数で、すべてのitemの数より大きくなければなりません.そうしないと、アップロードをトリガーすることはありません.考えてみてください. , , , , , , , item , .