Listview和RecycleView的简单比较

RecyclerView是ListView的增强版,适用于高效展示大量动态数据,支持布局管理器和动画效果。相比ListView,RecyclerView的优点包括视图复用、自定义布局和内置动画。然而,其缺点在于不便于添加头部和尾部,以及设置子项点击事件,需要额外的库和自定义实现。适合追求高效性能的场景,但使用上相对较复杂。
摘要由CSDN通过智能技术生成

谷歌说使用RecycleView的理由:

RecyclerView is a more advanced and flexible version of ListView. This
widget is a container for large sets of views that can be recycled and
scrolled very efficiently. Use the RecyclerView widget when you have
lists with elements that change dynamically.

它是ListView的更高度定制版,当你需要高效的展示大量数据时候,动态改变元素的列表的时候,就用这个。

优点:

当然,如果只是动态展示数据,listview也可以做到,用它替代listview的原因有几个:

  1. 简介中提到的它封装了viewholder的回收复用。
  2. RecyclerView使用布局管理器管理子view的位置(目前尚只提供了LinearLayoutManager),也就是说你再不用拘泥于ListView的线性展示方式,如果之后提供其他custom LayoutManager的支持,你能够使用复杂的布局来展示一个动态组件。

    StaggeredGridLayoutManager mStaggeredGridLayoutManager =
    new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
    //表示两列,并且是竖直方向的瀑布流
    mRecyclerView.setLayoutManager(mStaggeredGridLayoutManager);
    

    在布局上支持三种StaggeredGridLayoutManagerGridLayoutManager LinearLayoutManager

  3. 自带了ItemAnimation,可以设置加载和移除时的动画,方便做出各种动态浏览的效果。
  4. 分开的view
    我们平时用listview的时候,adapter一般这么写的

    if (convertView == null) {
          holder = new ViewHolder();
           LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
           convertView = inflater.inflate(
                   R.layout.list_device_binding, parent, false);
    
           holder.deviceImage = (ImageView) convertView
                   .findViewById(R.id.bluetoothDeviceImage);
           holder.deviceName = (TextView) convertView
                   .findViewById(R.id.bluetoothDeviceName);
           holder.deviceType = (TextView) convertView
                   .findViewById(R.id.bluetoothDeviceType);
           convertView.setTag(holder);
       } else {
           holder = (ViewHolder) convertView.getTag();
       }
    

    但是,到了这里,他把他分隔开了,如下

    @Override
    public A onCreateViewHolder(ViewGroup parent, int viewType) {       
        final View view = LayoutInflater.from(mContext).
              inflate(R.layout.listitem_track_history, parent, false);
        return new ViewHolder(view); 
     }  
    
    @Override
    public void onBindViewHolder(A holder, int position) {
         Data da=getData(position);
        holder.tvDate.setText(da.getDate());
    }
    

    我们就再也不用像以前那样写了.

  5. 相对简单
    我们看下Listview他背后的继承关系

    public class ListView extends AbsListView 
    public abstract class AbsListView extends AdapterView<ListAdapter>
    public abstract class AdapterView<T extends Adapter> extends ViewGroup 
    

    三重继承,内容还挺多的,不是直接继承ViewGroup,而相反的RecycleView却是直接继承自ViewGroup的。

缺点:

目前相对于我们对listview经常用到的方法,有下面两个问题:
1. 不能简单的加头和尾
2. 不能简单的设置子item的点击事件。

具体的解决方案如下

  1. 不能简单的添加Head和Footer
    在使用过程中,你发现你要添加头和尾不是很容易,因为没有直接的addHead和addFoot的方法了,不过这里有一个tumblr开源的库,可以让你实现这个功能,核心的代码如下

     @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        if (isHeader(viewType)) {
            int whichHeader = Math.abs(viewType - HEADER_VIEW_TYPE);
            View headerView = mHeaders.get(whichHeader);
            return new RecyclerView.ViewHolder(headerView) { };
        } else if (isFooter(viewType)) {
            int whichFooter = Math.abs(viewType - FOOTER_VIEW_TYPE);
            View footerView = mFooters.get(whichFooter);
            return new RecyclerView.ViewHolder(footerView) { };
    
        } else {
            return mBase.onCreateViewHolder(viewGroup, viewType);
        }
    }
    
    
    
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
            if (position < mHeaders.size()) {
                // Headers don't need anything special  
        } else if (position < mHeaders.size() + mBase.getItemCount()) {
            // This is a real position, not a header or footer. Bind it.
            mBase.onBindViewHolder(viewHolder, position - mHeaders.size()); 
        } else {
            // Footers don't need anything special
        }
    }
    
    
    
    @Override   
    public int getItemViewType(int position) {
        if (position < mHeaders.size()) {
            return HEADER_VIEW_TYPE + position;
    
    } else if (position < (mHeaders.size() + mBase.getItemCount())) {
        return mBase.getItemViewType(position - mHeaders.size());
    
    } else {
        return FOOTER_VIEW_TYPE + position - mHeaders.size() - mBase.getItemCount();
    }
    
  2. 不能简单的添加点击事件onListItemClickListener
    我们在使用listview设置子item的点击事件的时候,只需要像下面这么写

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
           @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    
               User user= parent.getItemAtPosition(position);                   
            }
    });
    

    但是,如果你使用这个RecycleView,会发现没有这个接口了。RecyclerView不再负责Item视图的布局及显示,所以RecyclerView也没有为Item开放OnItemClick等点击事件,这就需要我们自己实现,实现的方法像看到有三种,目前下面这种比较合理,所以推荐如下写法

    1. 让你的viewholder实现onClickListener,然后在这个方法里面回调我们自己写的接口。

      public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
      
          private TextView tvDate;             
      
          public ViewHolder(View itemView) {
              super(itemView);        
              tvDate = (TextView) itemView.findViewById(R.id.tv_date);
              itemView.setOnClickListener(this);
          }
      
          @Override
          public void onClick(View v) {
              if(listener!=null){
                  listener.onItemClick(getPosition(),mList.get(getPosition()));
              }
          }
      }
      
      //我们回调的自定义接口
      public  interface  onListItemClickListener{     
          void onItemClick(int position,TrackHistory mTrackHistory);
      }
      
    2. 接着在你的Adapter里面加多个set方法,里面设置回调接口

      public  void setOnItemClickListener(onListItemClickListener listener){      
          this.listener = listener;
      }
      

小结

从上面的简单比较,对于我而言如果不是最求很高的效率,我不选择用这个,确实有点不方便了


使用上并不是很方便。

参考来源:
android新组件RecyclerView使用介绍和进阶使用,替用Gallery:
Android-RecyclerView-Item点击事件设置

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值