374

ListViewに変更したいと思いRecyclerViewます。の を使用して、onScrollユーザーがリストの最後までスクロールしたかどうかを判断したいと考えています。OnScrollListenerRecyclerView

REST サービスから新しいデータをフェッチできるように、ユーザーがリストの最後までスクロールしたかどうかを知るにはどうすればよいですか?

4

36 に答える 36

174

これらの変数を作成します。

private int previousTotal = 0;
private boolean loading = true;
private int visibleThreshold = 5;
int firstVisibleItem, visibleItemCount, totalItemCount;

リサイクラー ビューのスクロールに設定します。

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);

        visibleItemCount = mRecyclerView.getChildCount();
        totalItemCount = mLayoutManager.getItemCount();
        firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();

        if (loading) {
            if (totalItemCount > previousTotal) {
                loading = false;
                previousTotal = totalItemCount;
            }
        }
        if (!loading && (totalItemCount - visibleItemCount) 
            <= (firstVisibleItem + visibleThreshold)) {
            // End has been reached

            Log.i("Yaeye!", "end called");

            // Do something

            loading = true;
        }
    }
});

注:LinearLayoutManagerのレイアウト マネージャとして使用していることを確認してくださいRecyclerView

LinearLayoutManager mLayoutManager;
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);

およびグリッドの場合

GridLayoutManager mLayoutManager;
mLayoutManager = new GridLayoutManager(getActivity(), spanCount);
mRecyclerView.setLayoutManager(mLayoutManager);

エンドレススクロールを楽しんでください!! ^.^

更新: mRecyclerView。setOnScrollListener()は非推奨です。置き換えるだけでmRecyclerView.addOnScrollListener()、警告はなくなります! この SO questionから詳細を読むことができます。

Android が Kotlin を正式にサポートするようになったため、同じものを更新します -

OnScrollListener を作成する

class OnScrollListener(val layoutManager: LinearLayoutManager, val adapter: RecyclerView.Adapter<RecyclerAdapter.ViewHolder>, val dataList: MutableList<Int>) : RecyclerView.OnScrollListener() {
    var previousTotal = 0
    var loading = true
    val visibleThreshold = 10
    var firstVisibleItem = 0
    var visibleItemCount = 0
    var totalItemCount = 0

    override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
        super.onScrolled(recyclerView, dx, dy)

        visibleItemCount = recyclerView.childCount
        totalItemCount = layoutManager.itemCount
        firstVisibleItem = layoutManager.findFirstVisibleItemPosition()

        if (loading) {
            if (totalItemCount > previousTotal) {
                loading = false
                previousTotal = totalItemCount
            }
        }

        if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {
            val initialSize = dataList.size
            updateDataList(dataList)
            val updatedSize = dataList.size
            recyclerView.post { adapter.notifyItemRangeInserted(initialSize, updatedSize) }
            loading = true
        }
    }
}

このように RecyclerView に追加します

recyclerView.addOnScrollListener(OnScrollListener(layoutManager, adapter, dataList))

完全なコード例については、この Github リポジトリを参照してください。

于 2014-10-25T11:09:35.687 に答える
76

最後のアイテムが完全に表示されたときにのみ通知を受け取りたい場合は、 を使用できますView.canScrollVertically()

これが私の実装です:

public abstract class OnVerticalScrollListener
        extends RecyclerView.OnScrollListener {

    @Override
    public final void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        if (!recyclerView.canScrollVertically(-1)) {
            onScrolledToTop();
        } else if (!recyclerView.canScrollVertically(1)) {
            onScrolledToBottom();
        } else if (dy < 0) {
            onScrolledUp();
        } else if (dy > 0) {
            onScrolledDown();
        }
    }

    public void onScrolledUp() {}

    public void onScrolledDown() {}

    public void onScrolledToTop() {}

    public void onScrolledToBottom() {}
}

注: recyclerView.getLayoutManager().canScrollVertically()API < 14 をサポートする場合に使用できます。

于 2015-05-23T08:31:11.870 に答える
74

ここに別のアプローチがあります。任意のレイアウト マネージャーで動作します。

  1. Adapter クラスを抽象化する
  2. 次に、アダプター クラスで抽象メソッドを作成します (例: load())。
  3. onBindViewHolderで、最後の場合は位置確認し、load() を呼び出します
  4. アクティビティまたはフラグメントでアダプター オブジェクトを作成するときに、load() 関数をオーバーライドします。
  5. オーバーライドされたロード関数で、loadmore 呼び出しを実装します

詳細を理解するために、私はブログ投稿とサンプル プロジェクトを書きました

MyAdapter.java

public abstract class MyAdapter extends RecyclerView.Adapter<ViewHolder>{

        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            //check for last item
            if ((position >= getItemCount() - 1))
                load();
        }

        public abstract void load();
}

MyActivity.java

public class MainActivity extends AppCompatActivity {
    List<Items> items;
    MyAdapter adapter;

   @Override
    protected void onCreate(Bundle savedInstanceState) {
    ...
    adapter=new MyAdapter(items){
            @Override
            public void load() {
                //implement your load more here
                Item lastItem=items.get(items.size()-1);
                loadMore();
            }
        };
   }
}
于 2015-08-20T05:24:22.643 に答える
14

私にとって、それは非常に簡単です:

     private boolean mLoading = false;

     mList.setOnScrollListener(new RecyclerView.OnScrollListener() {

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);

            int totalItem = mLinearLayoutManager.getItemCount();
            int lastVisibleItem = mLinearLayoutManager.findLastVisibleItemPosition();

            if (!mLoading && lastVisibleItem == totalItem - 1) {
                mLoading = true;
                // Scrolled to bottom. Do something here.
                mLoading = false;
            }
        }
    });

非同期ジョブには注意してください。非同期ジョブの最後に mLoading を変更する必要があります。それが役立つことを願っています!

于 2015-05-02T14:56:16.730 に答える
9

ほとんどの回答は、 、 または、または さえRecyclerView使用することを前提としているか、スクロールが垂直または水平であると想定していますが、完全に一般的な回答を投稿した人はいませんLinearLayoutManagerGridLayoutManagerStaggeredGridLayoutManager

のアダプターを使用するViewHolderことは、明らかに良い解決策ではありません。アダプターは、それを使用する複数のアダプターを持つ場合がありRecyclerViewます。それらの内容を「適応」させます。Recycler View (ユーザーに現在表示されているものを担当する 1 つのクラスであり、にコンテンツを提供することのみを担当するアダプターではRecyclerViewありません) である必要がありますロード)。

RecyclerView の抽象化されたクラス (RecycerView.LayoutManager および RecycerView.Adapter) 以外は何も使用しない私のソリューションを次に示します。

/**
 * Listener to callback when the last item of the adpater is visible to the user.
 * It should then be the time to load more items.
 **/
public abstract class LastItemListener extends RecyclerView.OnScrollListener {

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
      super.onScrolled(recyclerView, dx, dy);

      // init
      RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
      RecyclerView.Adapter adapter = recyclerView.getAdapter();

      if (layoutManager.getChildCount() > 0) {
        // Calculations..
        int indexOfLastItemViewVisible = layoutManager.getChildCount() -1;
        View lastItemViewVisible = layoutManager.getChildAt(indexOfLastItemViewVisible);
        int adapterPosition = layoutManager.getPosition(lastItemViewVisible);
        boolean isLastItemVisible = (adapterPosition == adapter.getItemCount() -1);

        // check
        if (isLastItemVisible)
          onLastItemVisible(); // callback
     }
   }

   /**
    * Here you should load more items because user is seeing the last item of the list.
    * Advice: you should add a bollean value to the class
    * so that the method {@link #onLastItemVisible()} will be triggered only once
    * and not every time the user touch the screen ;)
    **/
   public abstract void onLastItemVisible();

}


// --- Exemple of use ---

myRecyclerView.setOnScrollListener(new LastItemListener() {
    public void onLastItemVisible() {
         // start to load more items here.
    }
}
于 2016-11-10T11:21:33.710 に答える
7

受け入れられた答えは完全に機能しますが、setOnScrollListener は非推奨であるため、以下のソリューションでは addOnScrollListener を使用し、変数の数と if 条件を減らします。

final LinearLayoutManager layoutManager = new LinearLayoutManager(context);
feedsRecyclerView.setLayoutManager(layoutManager);

feedsRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);

        if (dy > 0) {   
            if ((layoutManager.getChildCount() + layoutManager.findFirstVisibleItemPosition()) >= layoutManager.getItemCount()) {
                Log.d("TAG", "End of list");
                //loadMore();
            }
        }
    }
});
于 2016-01-23T07:45:52.843 に答える
6

この質問には非常に多くの答えがありますが、エンドレス リスト ビューを作成した経験を共有したいと思います。最近、リストを無限にスクロールするだけでなく、特定のポイントまでスクロールすることで、サイクルで機能するカスタム Carousel LayoutManager を実装しました。GitHubの詳細な説明は次のとおりです。

カスタム LayoutManager の作成に関する短いが貴重な推奨事項を記載したこの記事をご覧になることをお勧めします: http://cases.azoft.com/create-custom-layoutmanager-android/

于 2016-07-13T08:10:44.333 に答える
4
 recyclerList.setOnScrollListener(new RecyclerView.OnScrollListener() 
            {
                @Override
                public void onScrolled(RecyclerView recyclerView, int dx,int dy)
                {
                    super.onScrolled(recyclerView, dx, dy); 
                }

                @Override
                public void onScrollStateChanged(RecyclerView recyclerView,int newState) 
                {
                    int totalItemCount = layoutManager.getItemCount();
                    int lastVisibleItem = layoutManager.findLastVisibleItemPosition();

                    if (totalItemCount> 1) 
                    {
                        if (lastVisibleItem >= totalItemCount - 1) 
                        {
                            // End has been reached
                            // do something 
                        }
                    }          
                }
            });  
于 2014-11-26T06:46:54.827 に答える
3

LayoutManager使用済み(例: )を拡張し、メソッドLinearLayoutManagerをオーバーライドしようとします。scrollVerticallyBy()まず、最初に呼び出しsuperてから、返された整数値を確認します。値が等しい場合0、下または上の境界に達しています。次に、findLastVisibleItemPosition()メソッドを使用して到達した境界を見つけ、必要に応じてさらにデータをロードします。ただのアイデア。

さらに、そのメソッドから値を返すこともでき、オーバースクロールを許可し、「読み込み中」インジケーターを表示できます。

于 2014-10-24T09:16:56.940 に答える
3

このpaginateという名前の使いやすいライブラリがあります。ListView と RecyclerView ( LinearLayout 、 GridLayout 、 StaggeredGridLayout ) の両方をサポートします。

ここにGithubのプロジェクトへのリンクがあります

于 2016-07-19T17:27:00.090 に答える
3

クラスのonBindViewHolderメソッドでこのロジックを使用して、無限スクロール型の実装を実現しました。RecyclerView.Adapter

    if (position == mItems.size() - 1 && mCurrentPage <= mTotalPageCount) {
        if (mCurrentPage == mTotalPageCount) {
            mLoadImagesListener.noMorePages();
        } else {
            int newPage = mCurrentPage + 1;
            mLoadImagesListener.loadPage(newPage);
        }
    }

このコードを使用すると、RecyclerView が最後のアイテムに到達すると、現在のページがインクリメントされ、API からより多くのデータをロードして新しい結果をアダプターに追加するインターフェイスでコールバックが行われます。

これが明確でない場合は、より完全な例を投稿できますか?

于 2014-11-19T17:34:49.870 に答える
3

ここでStaggeredGridLayoutManagerを使用する人にとっては、私の実装であり、私にとってはうまくいきます。

 private class ScrollListener extends RecyclerView.OnScrollListener {
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {

        firstVivisibleItems = mLayoutManager.findFirstVisibleItemPositions(firstVivisibleItems);

        if(!recyclerView.canScrollVertically(1) && firstVivisibleItems[0]!=0) {
            loadMoreImages();
        }

    }

    private boolean loadMoreImages(){
        Log.d("myTag", "LAST-------HERE------");
        return true;
    }
}
于 2015-07-12T17:08:29.840 に答える
2

RecyclerView を使用してページ分割する方法のかなり詳細な例があります。大まかに言えば、私は PAGE_SIZE を 30 に設定しています。つまり、30 個のアイテムをリクエストし、30 個返されたら次のページをリクエストします。取得したアイテムが 30 未満の場合は、変数にフラグを立てて最後のページに到達したことを示し、それ以上のページの要求を停止します。それをチェックして、あなたの考えを教えてください。

https://medium.com/@etiennelawlor/pagination-with-recyclerview-1cb7e66a502b

于 2015-11-18T21:45:52.520 に答える
2

ここで、Web でAsyncListUtilを使用する私のソリューションは次のように述べています。しかし、私は odata を使用してデータを読み取り、正常に動作しています。私の例のデータ エンティティとネットワーク メソッドが欠落しています。サンプル アダプターのみを含めます。

public class AsyncPlatoAdapter extends RecyclerView.Adapter {

    private final AsyncPlatoListUtil mAsyncListUtil;
    private final MainActivity mActivity;
    private final RecyclerView mRecyclerView;
    private final String mFilter;
    private final String mOrderby;
    private final String mExpand;

    public AsyncPlatoAdapter(String filter, String orderby, String expand, RecyclerView recyclerView, MainActivity activity) {
        mFilter = filter;
        mOrderby = orderby;
        mExpand = expand;
        mRecyclerView = recyclerView;
        mActivity = activity;
        mAsyncListUtil = new AsyncPlatoListUtil();

    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).
                inflate(R.layout.plato_cardview, parent, false);

        // Create a ViewHolder to find and hold these view references, and
        // register OnClick with the view holder:
        return new PlatoViewHolderAsync(itemView, this);
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        final Plato item = mAsyncListUtil.getItem(position);
        PlatoViewHolderAsync vh = (PlatoViewHolderAsync) holder;
        if (item != null) {
            Integer imagen_id = item.Imagen_Id.get();
            vh.getBinding().setVariable(BR.plato, item);
            vh.getBinding().executePendingBindings();
            vh.getImage().setVisibility(View.VISIBLE);
            vh.getProgress().setVisibility(View.GONE);
            String cacheName = null;
            String urlString = null;
            if (imagen_id != null) {
                cacheName = String.format("imagenes/imagen/%d", imagen_id);
                urlString = String.format("%s/menusapi/%s", MainActivity.ROOTPATH, cacheName);
            }
            ImageHelper.downloadBitmap(mActivity, vh.getImage(), vh.getProgress(), urlString, cacheName, position);
        } else {
            vh.getBinding().setVariable(BR.plato, item);
            vh.getBinding().executePendingBindings();
            //show progress while loading.
            vh.getImage().setVisibility(View.GONE);
            vh.getProgress().setVisibility(View.VISIBLE);
        }
    }

    @Override
    public int getItemCount() {
        return mAsyncListUtil.getItemCount();
    }

    public class AsyncPlatoListUtil extends AsyncListUtil<Plato> {
        /**
         * Creates an AsyncListUtil.
         */
        public AsyncPlatoListUtil() {
            super(Plato.class, //my data class
                    10, //page size
                    new DataCallback<Plato>() {
                        @Override
                        public int refreshData() {
                            //get count calling ../$count ... odata endpoint
                            return countPlatos(mFilter, mOrderby, mExpand, mActivity);
                        }

                        @Override
                        public void fillData(Plato[] data, int startPosition, int itemCount) {
                            //get items from odata endpoint using $skip and $top
                            Platos p = loadPlatos(mFilter, mOrderby, mExpand, startPosition, itemCount, mActivity);
                            for (int i = 0; i < Math.min(itemCount, p.value.size()); i++) {
                                data[i] = p.value.get(i);
                            }

                        }
                    }, new ViewCallback() {
                        @Override
                        public void getItemRangeInto(int[] outRange) {
                            //i use LinearLayoutManager in the RecyclerView
                            LinearLayoutManager layoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
                            outRange[0] = layoutManager.findFirstVisibleItemPosition();
                            outRange[1] = layoutManager.findLastVisibleItemPosition();
                        }

                        @Override
                        public void onDataRefresh() {
                            mRecyclerView.getAdapter().notifyDataSetChanged();
                        }

                        @Override
                        public void onItemLoaded(int position) {
                            mRecyclerView.getAdapter().notifyItemChanged(position);
                        }
                    });
            mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    onRangeChanged();
                }
            });
        }
    }
}
于 2016-06-17T21:13:50.767 に答える
1

@kushal @abdulaziz

代わりにこのロジックを使用してみませんか?

public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
    int totalItemCount, lastVisibleItemPosition;

    if (dy > 0) {
      totalItemCount = _layoutManager.getItemCount();
      lastVisibleItemPosition = _layoutManager.findLastVisibleItemPosition();

      if (!_isLastItem) {
        if ((totalItemCount - 1) == lastVisibleItemPosition) {
          LogUtil.e("end_of_list");

          _isLastItem = true;
        }
      }
    }
  }
于 2016-08-22T12:40:04.367 に答える
1

すべてが詳細に説明されていることを確認してください: RecyclerView From A to Z を使用したページネーション

    mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(RecyclerView recyclerView,
                                     int newState) {
        super.onScrollStateChanged(recyclerView, newState);
    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        int visibleItemCount = mLayoutManager.getChildCount();
        int totalItemCount = mLayoutManager.getItemCount();
        int firstVisibleItemPosition = mLayoutManager.findFirstVisibleItemPosition();

        if (!mIsLoading && !mIsLastPage) {
            if ((visibleItemCount + firstVisibleItemPosition) >= totalItemCount
                    && firstVisibleItemPosition >= 0) {
                loadMoreItems();
            }
        }
    }
})

loadMoreItems():

private void loadMoreItems() {
    mAdapter.removeLoading();
    //load data here from the server

    // in case of success
    mAdapter.addData(data);
    // if there might be more data
    mAdapter.addLoading();
}

MyAdapter で:

private boolean mIsLoadingFooterAdded = false;

public void addLoading() {
    if (!mIsLoadingFooterAdded) {
        mIsLoadingFooterAdded = true;
        mLineItemList.add(new LineItem());
        notifyItemInserted(mLineItemList.size() - 1);
    }
}

public void removeLoading() {
    if (mIsLoadingFooterAdded) {
        mIsLoadingFooterAdded = false;
        int position = mLineItemList.size() - 1;
        LineItem item = mLineItemList.get(position);

        if (item != null) {
            mLineItemList.remove(position);
            notifyItemRemoved(position);
        }
    }
}

public void addData(List<YourDataClass> data) {

    for (int i = 0; i < data.size(); i++) {
        YourDataClass yourDataObject = data.get(i);
        mLineItemList.add(new LineItem(yourDataObject));
        notifyItemInserted(mLineItemList.size() - 1);
    }
}
于 2016-02-23T23:29:10.620 に答える
1

以下を試してください:

import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.LayoutManager;

/**
 * Abstract Endless ScrollListener
 * 
 */
public abstract class EndlessScrollListener extends
        RecyclerView.OnScrollListener {
    // The minimum amount of items to have below your current scroll position
    // before loading more.
    private int visibleThreshold = 10;
    // The current offset index of data you have loaded
    private int currentPage = 1;
    // True if we are still waiting for the last set of data to load.
    private boolean loading = true;
    // The total number of items in the data set after the last load
    private int previousTotal = 0;
    private int firstVisibleItem;
    private int visibleItemCount;
    private int totalItemCount;
    private LayoutManager layoutManager;

    public EndlessScrollListener(LayoutManager layoutManager) {
        validateLayoutManager(layoutManager);
        this.layoutManager = layoutManager;
    }

    public EndlessScrollListener(int visibleThreshold,
            LayoutManager layoutManager, int startPage) {
        validateLayoutManager(layoutManager);
        this.visibleThreshold = visibleThreshold;
        this.layoutManager = layoutManager;
        this.currentPage = startPage;
    }

    private void validateLayoutManager(LayoutManager layoutManager)
            throws IllegalArgumentException {
        if (null == layoutManager
                || !(layoutManager instanceof GridLayoutManager)
                || !(layoutManager instanceof LinearLayoutManager)) {
            throw new IllegalArgumentException(
                    "LayoutManager must be of type GridLayoutManager or LinearLayoutManager.");
        }
    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        visibleItemCount = recyclerView.getChildCount();
        totalItemCount = layoutManager.getItemCount();
        if (layoutManager instanceof GridLayoutManager) {
            firstVisibleItem = ((GridLayoutManager) layoutManager)
                    .findFirstVisibleItemPosition();
        } else if (layoutManager instanceof LinearLayoutManager) {
            firstVisibleItem = ((LinearLayoutManager) layoutManager)
                    .findFirstVisibleItemPosition();
        }
        if (loading) {
            if (totalItemCount > previousTotal) {
                loading = false;
                previousTotal = totalItemCount;
            }
        }
        if (!loading
                && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {
            // End has been reached do something
            currentPage++;
            onLoadMore(currentPage);
            loading = true;
        }
    }

    // Defines the process for actually loading more data based on page
    public abstract void onLoadMore(int page);

}
于 2016-09-11T15:45:20.993 に答える
1

https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html#setOnScrollListener%28android.support.v7.widget.RecyclerView.OnScrollListener%29にメソッドpublic void setOnScrollListener (RecyclerView.OnScrollListener listener)があります。それを使って

編集:

onScrollStateChanged内のメソッドをオーバーライドonScrollListenerして、これを行います

            boolean loadMore = firstVisibleItem + visibleItemCount >= totalItemCount;

            //loading is used to see if its already loading, you have to manually manipulate this boolean variable
            if (loadMore && !loading) {
                 //end of list reached
            }
于 2014-10-24T07:15:15.907 に答える
1

リストが小さすぎるかどうかを考慮した回答はありません。

これは、RecycleViews で両方向に機能する、私が使用しているコードの一部です。

@Override
    public boolean onTouchEvent(MotionEvent motionEvent) {

        if (recyclerViewListener == null) {
            return super.onTouchEvent(motionEvent);
        }

        /**
         * If the list is too small to scroll.
         */
        if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
            if (!canScrollVertically(1)) {
                recyclerViewListener.reachedBottom();
            } else if (!canScrollVertically(-1)) {
                recyclerViewListener.reachedTop();
            }
        }

        return super.onTouchEvent(motionEvent);
    }

    public void setListener(RecyclerViewListener recycleViewListener) {
        this.recyclerViewListener = recycleViewListener;
        addOnScrollListener(new OnScrollListener() {

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                if (recyclerViewListener == null) {
                    return;
                }

                recyclerViewListener.scrolling(dy);

                if (!canScrollVertically(1)) {
                    recyclerViewListener.reachedBottom();
                } else if (!canScrollVertically(-1)) {
                    recyclerViewListener.reachedTop();
                }
            }

        });
    }
于 2016-05-04T09:55:34.180 に答える
-1

私はちょうどこれを試しました:

    final LinearLayoutManager rvLayoutManager = new LinearLayoutManager(this);
    rvMovieList = (RecyclerView) findViewById(R.id.rvMovieList);
    rvMovieList.setLayoutManager(rvLayoutManager);
    adapter = new MovieRecyclerAdapter(this, movies);
    rvMovieList.setAdapter(adapter);
    adapter.notifyDataSetChanged();

    rvMovieList.addOnScrollListener(new OnScrollListener() {
        boolean loading = true;
        int pastVisiblesItems, visibleItemCount, totalItemCount;
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);

            visibleItemCount = rvLayoutManager.getChildCount();
            totalItemCount = rvLayoutManager.getItemCount();
            pastVisiblesItems = rvLayoutManager.findFirstVisibleItemPosition();

            int lastitem = visibleItemCount + pastVisiblesItems;

            if ( lastitem == totalItemCount
                    && page < total_pages
                    && !keyword.equals("") ) {
                // hit bottom ..

                String strnext;
                if (page == total_pages - 1) {
                    int last = total_results - (page * 20);
                    strnext = String.format(getResources().getString(R.string.next), last);
                } else {
                    strnext = String.format(getResources().getString(R.string.next), 20);
                }
                btNext.setText(strnext);
                btNext.setVisibility(View.VISIBLE);
            } else {
                btNext.setVisibility(View.INVISIBLE);
            }

            if(pastVisiblesItems == 0 &&  page > 1){
                // hit top
                btPrev.setVisibility(View.VISIBLE);
            } else {
                btPrev.setVisibility(View.INVISIBLE);
            }
        }
    });

orloadingをどこに置くべきか混乱したので、それを削除しようとすると、このコードは期待どおりに機能します。truefalse

于 2018-02-04T15:52:22.303 に答える