RecyclerView上拉加载封装代码

发布时间 - 2026-01-11 02:58:11    点击率:

RecyclerView上拉加载,先看效果:

网上有很多这类得框架,不过在自己的项目只用到上拉加载的功能,所以自己封装一个简单点的。

主要依赖BaseRecyPRAdapter这类

public abstract class BaseRecyPRAdapter<T> extends RecyclerView.Adapter<BaseRecyPRAdapter.BaseViewHolder> {
  private static final String TAG = "BaseRecyPRAdapter";

  public static final int VIEW_ITEM = 0;
  public static final int VIEW_PROG = 1;

  public List<T> mDataList;

  private final Context mContext;
  private final RecyclerView mRecyclerView;
  private int totalItemCount;
  private int lastVisibleItemPosition;
  boolean isShowFootVieW = false;
  private Handler handler = new Handler();

  private static final int STATE_NORMAL = 0;
  private static final int STATE_LOADING = 1;
  private static final int STATE_LOAD_COMPLETE = 2;
  private int mState = STATE_NORMAL;

  public BaseRecyPRAdapter(Context context, RecyclerView recyclerView) {
    mContext = context;
    mRecyclerView = recyclerView;
    if (mRecyclerView.getLayoutManager() instanceof LinearLayoutManager) {
      final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();

      mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
          super.onScrollStateChanged(recyclerView, newState);
          int extent = recyclerView.computeVerticalScrollExtent();
          int range = recyclerView.computeVerticalScrollRange();
          Log.e(TAG, "\n extent = " + extent + "\n range = " + range);

          if (range > extent) {
            if(!isShowFootVieW){
              notifyDataSetChanged();
            }
            isShowFootVieW = true;
          } else {
            isShowFootVieW = false;
          }

          totalItemCount = linearLayoutManager.getItemCount();
          if (mState == STATE_NORMAL && newState == RecyclerView.SCROLL_STATE_IDLE &&
              totalItemCount == lastVisibleItemPosition + 1 && range > extent) {
            mState = STATE_LOADING;
            handler.post(new Runnable() {
              @Override
              public void run() {
                if (mLoadMoreDataListener != null) {
                  mLoadMoreDataListener.loadMoreData();
                }
              }
            });
          }
        }

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
          super.onScrolled(recyclerView, dx, dy);
          lastVisibleItemPosition = linearLayoutManager.findLastVisibleItemPosition();
        }
      });
    }

  }


  @Override
  public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    BaseViewHolder holder = null;
    View view = null;
    if (viewType == VIEW_PROG) {
      view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer, parent, false);
    } else {
      view = LayoutInflater.from(parent.getContext()).inflate(getLayoutId(viewType), parent, false);
    }
    holder = new BaseViewHolder(view);
    return holder;
  }


  @Override
  public void onBindViewHolder(BaseViewHolder holder, int position) {
    if (holder.getItemViewType() == BaseRecyPRAdapter.VIEW_PROG) {
//      LogTool.LogE_DEBUG(TAG, "onBindViewHolder--->" + mState);
      ProgressBar progressBar = (ProgressBar) holder.getView(R.id.progressbar);
      TextView text = (TextView) holder.getView(R.id.text);

      if (mState == STATE_LOAD_COMPLETE) {
        progressBar.setVisibility(View.GONE);
        text.setText(mContext.getString(R.string.没有数据了));
      } else {
        progressBar.setVisibility(View.VISIBLE);
        text.setText(mContext.getString(R.string.正在加载中));
      }
    }

    if (holder.getItemViewType() == BaseRecyPRAdapter.VIEW_ITEM) {
      onBindData(holder, position);
    }
  }

  @Override
  public int getItemCount() {
    if (isShowFootVieW) {
      return mDataList == null ? 0 : mDataList.size() + 1;
    } else {
      return mDataList == null ? 0 : mDataList.size();
    }
  }


  //根据不同的数据返回不同的viewType
  @Override
  public int getItemViewType(int position) {
    if (mDataList == null)
      return VIEW_ITEM;

    if (position == mDataList.size()) {
      return VIEW_PROG;
    } else {
      return VIEW_ITEM;
    }
  }

  /**
   * 根据type 返回不同的布局
   *
   * @param type
   * @return
   */
  public abstract int getLayoutId(int type);

  public abstract void onBindData(BaseViewHolder holder, int position);


  public static class BaseViewHolder extends RecyclerView.ViewHolder {
    private Map<Integer, View> mViewMap;
    public View view;

    public BaseViewHolder(View itemView) {
      super(itemView);

      view = itemView;
      mViewMap = new HashMap<>();
    }

    /**
     * 获取设置的view
     *
     * @param id
     * @return
     */
    public View getView(int id) {
      View view = mViewMap.get(id);
      if (view == null) {
        view = itemView.findViewById(id);
        mViewMap.put(id, view);
      }
      return view;
    }
  }

  public void stopLoadMore() {
    mState = STATE_NORMAL;
    notifyDataSetChanged();
  }

  public void loadComplete() {
    mState = STATE_LOAD_COMPLETE;
    notifyItemChanged(getItemCount()-1);
  }

  public void setData(List<T> datas) {
    mDataList = datas;
  }

  private LoadMoreDataListener mLoadMoreDataListener;

  public void setLoadMoreDataListener(LoadMoreDataListener mLoadMoreDataListener) {
    this.mLoadMoreDataListener = mLoadMoreDataListener;
  }

  public interface LoadMoreDataListener {
    void loadMoreData();
  }
}

在activity中使用:

public class MainActivity extends AppCompatActivity {

  private static final String TAG = "RecyActivity";
  private RecyclerView mRecyclerView;
  private List<String> list = new ArrayList<>();
  private MyRecyViewAdapter mAdapter;
  private Handler handler = new Handler();

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    init();
  }

  private void init() {
    initView();
    initData();

    initListener();
  }

  private void initView() {
    mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);

    //创建一个LinearLayoutManager对象
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(
        this, LinearLayoutManager.VERTICAL, false);
    mRecyclerView.setLayoutManager(linearLayoutManager);

    //创建adapter对象
    mAdapter = new MyRecyViewAdapter(this, mRecyclerView);
    mRecyclerView.setAdapter(mAdapter);
    mAdapter.setData(list);//设置数据
  }

  //初始化数据
  private void initData() {
    for (int i = 0; i < 15; i++) {
      list.add("DATA---------->" + i);
    }
  }


  //初始化监听
  private void initListener() {
    //加载更多回调监听
    mAdapter.setLoadMoreDataListener(new BaseRecyPRAdapter.LoadMoreDataListener() {
      @Override
      public void loadMoreData() {
        //加入null值此时adapter会判断item的type
        Log.e(TAG, "loadMoreData--->");
        handler.postDelayed(new Runnable() {
          @Override
          public void run() {
            if (list.size() < 30) {
              for (int i = 0; i < 5; i++) {
                list.add("LOAD MORE DATA---------->" + i);
              }
              mAdapter.stopLoadMore();
            } else {
              mAdapter.loadComplete();
            }
          }
        }, 500);
      }
    });
  }

  class MyRecyViewAdapter extends BaseRecyPRAdapter<String> {

    public MyRecyViewAdapter(Context context, RecyclerView recyclerView) {
      super(context, recyclerView);
    }

    @Override
    public int getLayoutId(int type) {
      return R.layout.item_view;
    }

    @Override
    public void onBindData(BaseViewHolder holder, int position) {
      Log.e(TAG, "onBindData--->" + position);
      if (mDataList == null || mDataList.isEmpty())
        return;

      TextView tv = (TextView) holder.getView(R.id.tv_name);
      if (tv != null) {
        tv.setText("DATA--------->" + position);
      }
    }
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# RecyclerView  # 上拉加载  # Android中使用RecyclerView实现下拉刷新和上拉加载  # Android RecyclerView实现下拉刷新和上拉加载  # Android RecyclerView 上拉加载更多及下拉刷新功能的实现方法  # Android使用recyclerview打造真正的下拉刷新上拉加载效果  # Android RecyclerView添加上拉加载更多效果  # android RecyclerView侧滑菜单  # 滑动删除  # 长按拖拽  # 下拉刷新上拉加载  # Android RecyclerView下拉刷新和上拉加载更多  # Android RecyclerView实现下拉刷新和上拉加载更多  # Android RecyclerView上拉加载更多功能回弹实现代码  # Android RecyclerView添加上拉加载更多功能  # 这类  # 加载  # 自己的  # 有很多  # 创建一个  # 回调  # 先看  # 大家多多  # 值此  # 简单点  # 加载中  # 网上  # OnScrollListener  # Override  # onScrollStateChanged  # range  # void  # computeVerticalScrollExtent  # extent  # newState 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 绝密ChatGPT指令:手把手教你生成HR无法拒绝的求职信  Laravel怎么导出Excel文件_Laravel Excel插件使用教程  详解MySQL数据库的安装与密码配置  如何在宝塔面板创建新站点?  Python企业级消息系统教程_KafkaRabbitMQ高并发应用  如何在Windows 2008云服务器安全搭建网站?  java获取注册ip实例  Laravel如何使用Socialite实现第三方登录?(微信/GitHub示例)  如何在自有机房高效搭建专业网站?  微信小程序 require机制详解及实例代码  如何在IIS服务器上快速部署高效网站?  Laravel如何实现密码重置功能_Laravel密码找回与重置流程  详解Android——蓝牙技术 带你实现终端间数据传输  如何自定义safari浏览器工具栏?个性化设置safari浏览器界面教程【技巧】  大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?  Python3.6正式版新特性预览  Laravel如何配置和使用缓存?(Redis代码示例)  在线教育网站制作平台,山西立德教育官网?  如何续费美橙建站之星域名及服务?  Midjourney怎样加参数调细节_Midjourney参数调整技巧【指南】  Android自定义listview布局实现上拉加载下拉刷新功能  Laravel的Blade指令怎么自定义_创建你自己的Laravel Blade Directives  b2c电商网站制作流程,b2c水平综合的电商平台?  Laravel怎么进行数据库事务处理_Laravel DB Facade事务操作确保数据一致性  如何在橙子建站上传落地页?操作指南详解  Laravel怎么配置自定义表前缀_Laravel数据库迁移与Eloquent表名映射【步骤】  智能起名网站制作软件有哪些,制作logo的软件?  香港服务器网站生成指南:免费资源整合与高速稳定配置方案  如何快速查询网址的建站时间与历史轨迹?  郑州企业网站制作公司,郑州招聘网站有哪些?  javascript中的数组方法有哪些_如何利用数组方法简化数据处理  Linux虚拟化技术教程_KVMQEMU虚拟机安装与调优  Laravel如何实现API版本控制_Laravel版本化API设计方案  Laravel如何使用Vite进行前端资源打包?(配置示例)  如何制作一个表白网站视频,关于勇敢表白的小标题?  如何快速查询域名建站关键信息?  Laravel如何安装使用Debugbar工具栏_Laravel性能调试与SQL监控插件【步骤】  Laravel策略(Policy)如何控制权限_Laravel Gates与Policies实现用户授权  手机怎么制作网站教程步骤,手机怎么做自己的网页链接?  php结合redis实现高并发下的抢购、秒杀功能的实例  如何批量查询域名的建站时间记录?  如何利用DOS批处理实现定时关机操作详解  Laravel如何使用Facades(门面)及其工作原理_Laravel门面模式与底层机制  网站制作软件有哪些,制图软件有哪些?  网站建设整体流程解析,建站其实很容易!  Laravel如何使用Gate和Policy进行授权?(权限控制)  Laravel怎么使用Blade模板引擎_Laravel模板继承与Component组件复用【手册】  Laravel路由Route怎么设置_Laravel基础路由定义与参数传递规则【详解】  laravel怎么在请求结束后执行任务(Terminable Middleware)_laravel Terminable Middleware请求结束任务执行方法  Java解压缩zip - 解压缩多个文件或文件夹实例