Как я могу определить, что последний элемент RecyclerView отображается на экране?

У меня есть один RecyclerView и я добавил список данных в RecyclerView. Я хотел добавить больше данных в список, когда последний элемент RecyclerView виден на экране. После этого я хочу сделать вызов веб-службы и обновить данные RecyclerView. Как мне этого добиться?

Какие-либо предложения?

Ответ 1

Существует несколько способов сделать это, но одним из способов было бы использовать метод адаптера onBindViewHolder:

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (position == mData.length - 1) {
            // load more data here.
        }

        /// binding logic
    }

Когда метод связывания вызывается с последней позицией вашего источника данных, это хороший признак того, что последняя ячейка будет отображаться, и хорошее время для запуска вызова перезагрузки. Возможно, вам придется добавить дополнительные условия в состояние, чтобы убедиться, что вы еще не загружаете больше данных, но это должно помочь вам начать работу.

Другим вариантом будет редактирование вашего LayoutManager. Идея здесь состоит в том, чтобы найти позицию последнего видимого элемента. Если эта позиция равна последнему элементу вашего набора данных, вы должны вызвать перезагрузку. Этот вызов должен выполняться в ваших методах LayourManager's onLayoutChildren и scrollVerticallyBy (при использовании методов вертикальной прокрутки):

    @Override
    public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {

        final int result = super.scrollVerticallyBy(dy, recycler, state);

        if (findLastVisibleItemPosition() == mData.length - 1) {
           loadMoreData();
        } 

        return result;

    }

    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        super.onLayoutChildren(recycler, state);

        if (findLastVisibleItemPosition() == mData.length - 1) {
           loadMoreData();
        } 
    }

Как и раньше, вам необходимо убедиться, что вы не запускаете загрузку данных более одного раза, так как это возможно, это условие будет происходить более одного раза.

Надеюсь, это поможет!

Ответ 2

Если кто-то наткнется на этот пост, это быстрый и простой урок о том, как это сделать:

Все, что вам нужно сделать, это:

recyclerView.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        = lm.getChildCount();
        int totalItemCount          = lm.getItemCount();
        int firstVisibleItemPosition= lm.findFirstVisibleItemPosition();

        // Load more if we have reach the end to the recyclerView
        if ( (visibleItemCount + firstVisibleItemPosition) >= totalItemCount && firstVisibleItemPosition >= 0) {
            loadMoreItems();
        }
    }
});

Тогда ваш loadMoreItems() должен выглядеть примерно так:

private void loadMoreItems() {
    // init offset=0 the frist time and increase the offset + the PAGE_SIZE when loading more items
    queryOffset = queryOffset + PAGE_SIZE;
    // HERE YOU LOAD the next batch of items
    List<Items> newItems = loadItems(queryOffset, PAGE_SIZE);

    if (newItems.size() > 0) {
        items.addAll(newItems);
        adapter.notifyDataSetChanged();
    }
}

Ответ 3

@Override
public void onBindViewHolder(final RecyclerView.ViewHolderholder, int position) {

    if (!list.isEmpty() || list== null) {

        if (position == (list.size() - 1)) {

            // add new data (add data to list)
            this.notifyDataSetChanged();

        }

    }


}