美文网首页程序员
RecyclerView多层嵌套列表的实现,加下拉刷新上拉加载。

RecyclerView多层嵌套列表的实现,加下拉刷新上拉加载。

作者: 永远爱你ol | 来源:发表于2020-12-14 16:04 被阅读0次

    RecyclerView是安卓中比较常用的列表控件了,当然刚接触这个控件的时候肯定也会遇到很多问题。接下来分享一下自己遇到的问题和解决方法。


    20201214-135552.png

    像上图这种列表就需要双层嵌套了,接下来我们先创建RecyclerView控件。

     RecyclerView ListView = (RecyclerView)findViewById(R.id.adapter_list);
            LinearLayoutManager layoutManager = new LinearLayoutManager(this);
            ListView.setLayoutManager(layoutManager);
            ListView.addItemDecoration(new SpacesItemDecoration(14));
            adapter = new JiankangpersonAdapter(DActivity.this,heathList);
            ListView.setAdapter(adapter);
            appRefresh();//下拉刷新
            EndLessOnScrollListener.reSet(); //上拉加载
              ListView.addOnScrollListener(new EndLessOnScrollListener(layoutManager) {
                @Override
                public void onLoadMore(int currentPage) {
                   //需要加载的数据
                }
              });
    

    附上对应的adapt的代码,其中包括了实现上拉加载的功能。

    public class JiankangpersonAdapter extends  RecyclerView.Adapter<RecyclerView.ViewHolder>{
        private List<HeathpersonUserinfo> mDatas;
        private Context context;
        private int normalType = 0;     // 第一种ViewType,正常的item
        private int footType = 1;       // 第二种ViewType,底部的提示View
        private boolean fadeTips = false; // 变量,是否隐藏了底部的提示
        public JiankangpersonAdapter(Context context, List<HeathpersonUserinfo> data){
            mDatas = data;
            this.context = context;
        }
    
      class NormalHolder extends RecyclerView.ViewHolder {
        public TextView date;
        public RecyclerView persondetailList;
    
        public NormalHolder(View v) {
          super(v);
          date=(TextView)v.findViewById(R.id.person_date);
          persondetailList = (RecyclerView)v.findViewById(R.id.jiankangpersoninfo_list);
        }
      }
    
      class FootHolder extends RecyclerView.ViewHolder {
        private TextView tips;
    
        public FootHolder(View itemView) {
          super(itemView);
          tips = (TextView) itemView.findViewById(R.id.tips);
        }
      }
    
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
          if (viewType == normalType) {
            NormalHolder normalHolder =new NormalHolder (LayoutInflater.from(parent.getContext()).inflate(R.layout.view_jiankangperson, parent, false));
            return normalHolder;
          }else{
            return new FootHolder(LayoutInflater.from(context).inflate(R.layout.foot_item, null));
          }
        }
        @Override
        public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
          if (holder instanceof  NormalHolder) {
            HeathpersonUserinfo huser = mDatas.get(position);
            ((NormalHolder)holder).date.setText(huser.getDate());
            ((NormalHolder)holder).date.setTextColor(Color.parseColor("#557ac4"));
            holder.itemView.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                //Toast.makeText(context, "点击了", Toast.LENGTH_SHORT).show();
              }
            });
            ((NormalHolder)holder).persondetailList.setLayoutManager(new LinearLayoutManager(context));
            //holder.persondetailList.addItemDecoration(new SpacesItemDecoration(4));
            final JiankangpersonInfoAdapter checkinfoAdapter = new JiankangpersonInfoAdapter(context,huser.getPersondetail());
            ((NormalHolder)holder).persondetailList.setAdapter(checkinfoAdapter);
          }else{
            ((JiankangpersonAdapter.FootHolder) holder).tips.setVisibility(View.VISIBLE);
            if (EndLessOnScrollListener.isHasMore() == false) {
              fadeTips = false;
              if (mDatas.size() > 0) {
                ((JiankangpersonAdapter.FootHolder) holder).tips.setText("正在加载更多...");
              }
            } else {
              if (mDatas.size() > 0) {
                ((JiankangpersonAdapter.FootHolder) holder).tips.setText("没有更多数据了");
              }else {
                ((JiankangpersonAdapter.FootHolder) holder).tips.setVisibility(View.GONE);
              }
            }
          }
        }
    
        @Override
        public int getItemCount() {
            return mDatas.size()+1;
        }
    
      @Override
      public int getItemViewType(int position) {
        if (position == getItemCount() - 1) {
          return footType;
        } else {
          return normalType;
        }
      }
    }
    
    

    最关键的是这一部分,在最后加上这段代码,就可以实现在当前列表循环之下,再嵌套一层循环。

     ((NormalHolder)holder).persondetailList.setLayoutManager(new LinearLayoutManager(context));
     final JiankangpersonInfoAdapter checkinfoAdapter = new JiankangpersonInfoAdapter(context,huser.getPersondetail());
      ((NormalHolder)holder).persondetailList.setAdapter(checkinfoAdapter);
    

    因为JiankangpersonInfoAdapter中不需要添加上拉加载的功能,所以adapter的结构是有所区别的(结构示例如下)。

    public class JiankangpersonInfoAdapter extends  RecyclerView.Adapter<JiankangpersonInfoAdapter.VH>{
      static class VH extends RecyclerView.ViewHolder{
    
        public TextView type1;
        public TextView typekuohao;
        public VH(View v) {
          super(v);
          type1=(TextView)v.findViewById(R.id.jiankang_info_type);
          typekuohao=(TextView)v.findViewById(R.id.jiankang_info_typekuohao);
        }
      }
    
      private List<CheckInfo> mDatas;
      private Context context;
    
      public JiankangpersonInfoAdapter(Context context, List<CheckInfo> data){
        mDatas = data;
        this.context = context;
      }
    
      @NonNull
      @Override
      public JiankangpersonInfoAdapter.VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_jiankangperson_info, parent, false);
        final JiankangpersonInfoAdapter.VH holder = new JiankangpersonInfoAdapter.VH(v);
    
        return holder;
      }
      @Override
      public void onBindViewHolder(@NonNull VH holder, int position) {
          holder.type1.setText("起床");
          holder.typekuohao.setText("(生活)");
          holder.itemView.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
            //Toast.makeText(context, "点击了详情", Toast.LENGTH_SHORT).show();
          }
        });
      }
      public List<HeathpersonRecorddetail> initData(String recordId){
        List<HeathpersonRecorddetail> heathList = new ArrayList<HeathpersonRecorddetail>();
        return heathList;
      }
    
      @Override
      public int getItemCount() {
        return mDatas.size();
      }
    
      //  删除数据
      public void removeData(int position) {
        mDatas.remove(position);
        //删除动画
        notifyItemRemoved(position);
        notifyDataSetChanged();
      }
      //dp转px
      public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
      }
    }
    

    下拉刷新首先添加如下代码。

     private SwipeRefreshLayout swipeRefreshLayout;
        Handler handlerForRefresh = new Handler() {
        @Override
        public void handleMessage(Message msg) {
          switch (msg.what) {
            case 0x93: {
              swipeRefreshLayout.setRefreshing(false);
            }
          }
        }
      };
    

    然后是appRefresh()方法。

    private void appRefresh(){
        swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);
        swipeRefreshLayout.setColorSchemeResources(R.color.blue);
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
          @Override
          public void onRefresh() {
            new Thread(){
              @Override
              public void run () {
                super.run();
                //同步加载网络数据
                //加载数据 完毕后 关闭刷新状态 切回主线程
                handlerForRefresh.postDelayed(new Runnable() {
                  @Override
                  public void run() {
                   //需要刷新的数据
    
                    EndLessOnScrollListener.reSet();//重置上拉加载的设置
                    // 通知结束下拉刷新
                    handlerForRefresh.sendEmptyMessage(0x93);
                  }
                }, 100);
              }
            }.start();
          }
        });
      }
    

    其中swipe_refresh_layout是需要在xml文件中添加的。

     <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swipe_refresh_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
      <android.support.v7.widget.RecyclerView
            android:id="@+id/jiankang_list"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </android.support.v4.widget.SwipeRefreshLayout>
    

    上拉加载中关键的类 EndLessOnScrollListener。

    public abstract class EndLessOnScrollListener extends  RecyclerView.OnScrollListener{
    
      //声明一个LinearLayoutManager
      private LinearLayoutManager mLinearLayoutManager;
    
      //当前页,从0开始
      private static int currentPage = 1;
      //已经加载出来的Item的数量
      private static int totalItemCount;
    
      //主要用来存储上一个totalItemCount
      private static int previousTotal;
    
      //在屏幕上可见的item数量
      private static int visibleItemCount;
    
      //在屏幕可见的Item中的第一个
      private static int firstVisibleItem;
    
      //是否正在上拉数据
      private static boolean loading = true;
    
      private static boolean  hasMore=true;
    
      private int recordFlag=0;
    
      public EndLessOnScrollListener(LinearLayoutManager linearLayoutManager) {
        this.mLinearLayoutManager = linearLayoutManager;
      }
    
      @Override
      public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        visibleItemCount = recyclerView.getChildCount();
        totalItemCount = mLinearLayoutManager.getItemCount();
        firstVisibleItem = mLinearLayoutManager.findFirstVisibleItemPosition();
        if(recordFlag!=0){
          if(loading){
            if(totalItemCount > previousTotal){
              //说明数据已经加载结束
              hasMore=false;
              loading = false;
              previousTotal = totalItemCount;
            }
          }
          if (!loading && totalItemCount-visibleItemCount <= firstVisibleItem){
            hasMore=true;
            currentPage ++;
            onLoadMore(currentPage);
            loading = true;
          }
        }
          recordFlag++;
      }
    
      public  static void reSet(){
        currentPage=1;
        totalItemCount=0;
        previousTotal=0;
        visibleItemCount=0;
        firstVisibleItem=0;
        loading=true;
        hasMore=true;
      }
    
      public static boolean isHasMore() {
        return hasMore;
      }
      /**
       * 提供一个抽闲方法,在Activity中监听到这个EndLessOnScrollListener
       * 并且实现这个方法
       * */
      public abstract void onLoadMore(int currentPage);}
    

    注:其中关于页面的xml文件在这边全部省略了。

    相关文章

      网友评论

        本文标题:RecyclerView多层嵌套列表的实现,加下拉刷新上拉加载。

        本文链接:https://www.haomeiwen.com/subject/hdevgktx.html