📜  recyclerview 加载更多结束 (1)

📅  最后修改于: 2023-12-03 15:34:41.628000             🧑  作者: Mango

RecyclerView 加载更多结束

RecyclerView 是 Android 平台上一个非常常用的控件,主要用于展示大量数据的列表。在使用 RecyclerView 时,我们通常需要实现数据的分批加载,这个过程就需要考虑如何判断加载更多的条件以及如何结束加载。本文将介绍如何在 RecyclerView 中实现加载更多结束。

加载更多的实现

在 RecyclerView 中实现加载更多可以使用 Paging Library 或者自行实现分批加载逻辑。这里我们以自行实现分批加载逻辑为例。

在实现分批加载时,我们需要考虑以下几个问题:

  1. 定义列表中每一批数据的大小,如每批加载 20 条数据。

  2. 当列表滑动到底部时触发更多数据的加载,如向后台请求下一批数据。

  3. 在新数据加载出来前显示正在加载的动画。

  4. 当全部数据加载完毕时应该结束加载更多。

下面是一个自行实现分批加载的 RecyclerView 的代码:

public class MyAdapter extends RecyclerView.Adapter<MyViewHolder>
    implements OnLoadMoreListener {

  private List<MyData> mData;
  private boolean mIsLoading;
  private OnLoadMoreListener mOnLoadMoreListener;

  public void setOnLoadMoreListener(OnLoadMoreListener listener) {
    mOnLoadMoreListener = listener;
  }

  @Override
  public void onBindViewHolder(MyViewHolder holder, int position) {
    if (position == getItemCount() - 1 && mIsLoading) {
      // 正在加载数据,显示加载更多的动画
      holder.showLoadingAnimation();
      if (mOnLoadMoreListener != null) mOnLoadMoreListener.onLoadMore();
    } else {
      // 显示数据
      holder.showData(mData.get(position));
    }
  }

  @Override
  public int getItemCount() {
    return mData.size() + (mIsLoading ? 1 : 0);
  }

  @Override
  public int getItemViewType(int position) {
    return mIsLoading && position == getItemCount() - 1
        ? VIEW_TYPE_LOADING
        : VIEW_TYPE_DATA;
  }

  @Override
  public void onLoadMore() {
    // 触发加载更多数据的操作
    // 1. 向后台请求下一批数据
    // 2. 将新数据添加到 mData 中
    // 3. 调用 notifyDataSetChanged() 刷新列表
    // 4. 结束加载更多状态
  }

  public void setLoading(boolean isLoading) {
    mIsLoading = isLoading;
    notifyDataSetChanged();
  }
}

上述代码实现了一个加载更多的 RecyclerView,主要思路是在 onBindViewHolder 方法中判断当前项是否为加载更多的动画,如果是则触发设置的加载更多监听器,请求新数据并添加至数据列表中。同时,在 getItemCount 方法中需要根据是否正在加载状态来返回正确的列表条目数量。最后,当新数据加载完后需要刷新列表并结束加载状态。

加载更多结束的实现

当所有数据都被加载完成时,需要结束加载更多的状态。有两种常用的方式可以实现:

  • 隐藏加载更多的视图:这种方式下,我们可以在加载完所有数据后,将加载更多的视图直接移除,这样用户就无法通过滑动列表来触发加载更多的操作了。这种实现方式代码简单,但是无法让用户知道数据已经全部加载完成,用户可能会以为列表还能加载新的数据。为了让用户知道数据已经全部加载完成,我们可以添加一个空白视图提示用户列表已经到底了。

  • 显示加载完成的提示:这种方式下,我们可以在列表的底部显示一个提示,“已全部加载完成”,这样用户一看到提示就知道数据已经全部加载完成了。相对于隐藏加载更多的视图,这种实现方式需要添加更多的代码,但是用户体验相对比较好。我们可以在 Adapter 的 onLoadMore 方法中加入判断,当没有新数据时,设置加载完成标志位,更新界面即可。

下面是简单演示隐藏加载更多的视图的代码:

public class MyAdapter extends RecyclerView.Adapter<MyViewHolder>
    implements OnLoadMoreListener {

  // ...

  private boolean mIsAllLoaded; // 标记是否全部加载完成

  @Override
  public int getItemCount() {
    return mData.size() + (mIsLoading ? 1 : 0) + (mIsAllLoaded ? 1 : 0);
  }

  @Override
  public int getItemViewType(int position) {
    if (mIsAllLoaded && position == getItemCount() - 1) {
      // 加载完成,显示提示视图
      return VIEW_TYPE_TIP;
    } else if (mIsLoading && position == getItemCount() - 1) {
      // 正在加载数据,显示加载更多的动画
      return VIEW_TYPE_LOADING;
    } else {
      // 显示数据
      return VIEW_TYPE_DATA;
    }
  }

  @Override
  public void onLoadMore() {
    if (mIsAllLoaded) {
      return; // 当前已经全部加载完成了
    }

    // 触发加载更多数据的操作
    // 1. 向后台请求下一批数据
    // 2. 将新数据添加到 mData 中
    // 3. 调用 notifyDataSetChanged() 刷新列表
    // 4. 结束加载更多状态或设置加载完成标志位
    boolean hasNewData = false; // 标记是否有新数据
    if (hasNewData) {
      // 有新数据,结束加载更多状态
      setLoading(false);
    } else {
      // 没有新数据,全部数据已加载完成,显示提示视图
      mIsAllLoaded = true;
      notifyItemInserted(getItemCount() - 1);
    }
  }
}

上述代码在 Adapter 中新增了一个标记变量 mIsAllLoaded,用来标记是否全部加载完成。当新数据加载完之后,我们需要判断是否将所有数据都加载完成,并相应地更新界面。这里我们直接移除了加载更多的视图,当列表滑动到底部时,用户就无法继续加载更多数据了。

如果你希望展示加载完成的提示文字,那么可以在 getItemViewType 方法中新增一个类型,用来显示提示视图。同时,在 Adapter 的 onLoadMore 方法中需要加入判断,当没有新数据时,设置加载完成标志位,更新界面显示提示视图即可。

判断加载更多是否全部结束可以通过后台接口返回的数据的 total 数量是否等于列表数据的总数得知。如果相等则说明已经加载全部数据。