【问题标题】:How to implement pagination in RecyclerView on scroll如何在 RecyclerView 中实现滚动分页
【发布时间】:2016-01-02 11:54:12
【问题描述】:

Recyclerview 带有自己的滚动监听器,它有以下方法:

void onScrollStateChanged(RecyclerView recyclerView, int newState)

RecyclerView 的滚动状态改变时调用的回调方法。

void onScrolled(RecyclerView recyclerView, int dx, int dy)

RecyclerView 滚动时调用的回调方法。

当滚动到列表末尾时,有什么方法可以触发加载器加载更多数据?

我是这样实现的:

@Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
    GenerItem generItem=generItems.get(i);
    Log.d("TAG","position "+i);
    if(i==generItems.size()-1)
    ((GenerSearchActivity)mContext).onScroll(i);
    viewHolder.bindValues(generItem);
}

这里onScroll()在Activity中,会触发loader加载更多数据。请建议最好的方法是什么。

【问题讨论】:

  • 你的方法不行吗?
  • 它可以工作,但我不确定它是否是一个很好的方法,或者是否有其他方法可以实现此功能。
  • 这似乎是一个合理的方法!
  • 如果我不能通过你的代码示例,如何实现它。

标签: android pagination android-recyclerview


【解决方案1】:

在滚动结束时拨打下一个电话

基本上有 3 个步骤。

  1. 列表滚动时通知
  2. 进行 REST 调用(用于 NEXT 页面)
  3. 在旧列表中添加结果+通知数据集更改

回调

但首先,我们需要一个 Callback,它可以作为 RecyclerView.Adapter 和 Activity 之间的桥梁

public interface PaginationCallBack{
     public void oadNextPage();
}

在您的活动中实现此回调

class YourActivity extends AppCompatActivity implements PaginationCallBack{

     int pageNum = 1;

     @Override
     public void loadNextPage(){
           // Your implementation
     }
}

在 RecyclerView.Adapter 中初始化回调

class YourAdapter extends RecyclerView.Adapter{

     private PaginationCallBack paginationCallBack;

     public YourAdapter(PaginationCallBack paginationCallBack) {
        this.paginationCallBack = paginationCallBack;
     }

}

第 1 步onBindViewHolder 方法中添加条件并通过回调通知。

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewholder, int position) {

    if(position+1==images.size()){
        paginationCallBack.loadNextPage();  // Callback
    }

}

第 2 步: 调用 NEXT 页面

getImages(++pageNum) // 你的 REST 方法的页码

@Override
public void loadNextPage(){
    getImages(++pageNumber) // REST call with next Page 
}

第 3 步将结果添加到旧列表中并通知 datasetChanged

public void getImages(int pageNum){

      List<Images> newResults = //RESTCALL
      imageList.addAll(newResults);
      adapter.updateDataSet(imageList)

}

updateDataSet(imageList) 方法在哪里?

在RecyclerView.Adapter里面写这个方法

 public void updateDataSet(List<GalleryMedia> newImages){

    if(newImages!=null){
        images = newImages;
    }

    notifyDataSetChanged();
}

完整代码

RecyclerView Pagination

结果:

【讨论】:

  • 有用的代码。但是滑下来怎么样?
  • 您能详细说明一下吗? @SHemaNandhini
【解决方案2】:

这是一个滚动监听器,它实现了加载更多和快速返回模式:

public abstract class HidingScrollListener extends RecyclerView.OnScrollListener {

    private static final float  HIDE_THRESHOLD   = 10;
    private static final float  SHOW_THRESHOLD   = 70;

    private int                 mToolbarOffset   = 0;
    private boolean             mControlsVisible = true;
    private int                 mToolbarHeight;
    private int                 mTotalScrolledDistance;
    private int                 previousTotal    = 0;
    private boolean             loading          = true;
    private int                 visibleThreshold = 4;
    int                         firstVisibleItem, visibleItemCount, totalItemCount;
    private LinearLayoutManager layoutManager;

    public HidingScrollListener(Context context, LinearLayoutManager layoutManager) {
        mToolbarHeight = Tools.getFooterHeight(context);
        this.layoutManager = layoutManager;
    }

    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);

        if (newState == RecyclerView.SCROLL_STATE_IDLE) {
            if (mTotalScrolledDistance < mToolbarHeight) {
                setVisible();
            }
            else {
                if (mControlsVisible) {
                    if (mToolbarOffset > HIDE_THRESHOLD) {
                        setInvisible();
                    }
                    else {
                        setVisible();
                    }
                }
                else {
                    if ((mToolbarHeight - mToolbarOffset) > SHOW_THRESHOLD) {
                        setVisible();
                    }
                    else {
                        setInvisible();
                    }
                }
            }
        }

    }

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

        clipToolbarOffset();
        onMoved(mToolbarOffset);

        if ((mToolbarOffset < mToolbarHeight && dy > 0) || (mToolbarOffset > 0 && dy < 0)) {
            mToolbarOffset += dy;
        }
        if (mTotalScrolledDistance < 0) {
            mTotalScrolledDistance = 0;
        }
        else {
            mTotalScrolledDistance += dy;
        }
        // for load more
        visibleItemCount = recyclerView.getChildCount();
        totalItemCount = layoutManager.getItemCount();
        firstVisibleItem = layoutManager.findFirstVisibleItemPosition();

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

            loading = true;
            onLoadMore();
        }
    }

    private void clipToolbarOffset() {
        if (mToolbarOffset > mToolbarHeight) {
            mToolbarOffset = mToolbarHeight;
        }
        else if (mToolbarOffset < 0) {
            mToolbarOffset = 0;
        }
    }

    private void setVisible() {
        if (mToolbarOffset > 0) {
            onShow();
            mToolbarOffset = 0;
        }
        mControlsVisible = true;
    }

    private void setInvisible() {
        if (mToolbarOffset < mToolbarHeight) {
            onHide();
            mToolbarOffset = mToolbarHeight;
        }
        mControlsVisible = false;
    }

    public abstract void onMoved(int distance);

    public abstract void onShow();

    public abstract void onHide();

    public abstract void onLoadMore();
}

它的实现如下:

HidingScrollListener scrollListener = new HidingScrollListener(activity, manager) {
         @Override
         public void onMoved(int distance) {

         }

         @Override
         public void onShow() {

         }

         @Override
         public void onHide() {

         }

         @Override
         public void onLoadMore() {
            // you can do your pagination here.
         }
      };
      mRecyclerView.addOnScrollListener(scrollListener);

【讨论】:

    猜你喜欢
    • 2021-12-05
    • 2017-05-05
    • 1970-01-01
    • 1970-01-01
    • 2019-08-06
    • 2017-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多