如何在RecyclerView中实现滚动时的分页功能?

问题描述 投票:0回答:2

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() 活动中,将触发加载器加载更多的数据。最好的方法是什么,请建议。

android android-recyclerview recycler-adapter
2个回答
0
投票

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

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);

0
投票

在滚动结束时进行下一个调用

enter image description here

基本上有3个步骤。

  1. 列表滚动时通知
  2. 进行REST调用(用于下一页
  3. 在旧列表中添加结果+通知数据集变化

回电

但首先,我们需要一个回调,作为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;
     }

}

第一步增加一个条件 onBindViewHolder 方法,并用Callback通知。

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

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

}

第二步: 调用 "下一页 "方法

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

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

第三步 将结果添加到旧的列表中,并通知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();
}

完整代码

回收商查看分页

结果:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.