ListView 与 RecyclerView区别总结

5,380 阅读3分钟

参考

ListView 与 RecyclerView 简单对比

简单实用

ListView 的实现

  1. 继承重写BaseAdapter类;
  2. 自定义ViewHolder与convertView的优化(判断是否为null);

public class TestAdapter extends ArrayAdapter {
  public TestAdapter(@NonNull Context context, int resource) {
    super(context, resource);
    resourceId = resource;
  }
  @NonNull
  @Override
  public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
    // 获取当前项的数据实例
    Fruit fruit = getItem(position);
    View view;
    ViewHolder viewHolder;
    // convertView是将我们加载好的布局进行缓存
    if (convertView == null) {
      view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);
      viewHolder = new ViewHolder();
      viewHolder.textView = view.findViewById(R.id.fruit_name);
      view.setTag(viewHolder);
    } else {
      view = convertView;
      viewHolder = (ViewHolder) view.getTag();
    }
    viewHolder.textView.setText(fruit.getName());
    return view;
  }
  // 定义内部类
  class ViewHolder {
    TextView textView;
  }
}

......

      // listView 与 adapter 关联

        FruitAdapter adapter = new FruitAdapter(MainActivity.this,R.layout.fruit_item,fruitList);
        ListView listView = findViewById(R.id.list_view);
        listView.setAdapter(adapter);

RecyclerView 的实现

  1. 继承重写RecyclerView.Adapter与RecyclerView.ViewHolder
  2. 设置LayoutManager,以及layout的布局效果

// 第一步:继承重写 RecyclerView.Adapter 和 RecyclerView.ViewHolder
public class AuthorRecyclerAdapter extends RecyclerView.Adapter<AuthorRecyclerAdapter.AuthorViewHolder> {
    ...
    @Override
    public AuthorViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        ...
        return viewHolder;
    }
    @Override
    public void onBindViewHolder(AuthorViewHolder holder, int position) {
        ...
    }
    @Override
    public int getItemCount() {
        if (mData == null) {
            return 0;
        }
        return mData.size();
    }
    class AuthorViewHolder extends RecyclerView.ViewHolder {
        ...
        public AuthorViewHolder(View itemView) {
            super(itemView);
            ...
        }
    }
}
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mRecyclerAdapter = new AuthorRecyclerAdapter(mData);
// 第二步:设置布局管理器,控制布局效果
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(RecyclerDemoActivity.this);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(linearLayoutManager);
mRecyclerView.setAdapter(mRecyclerAdapter);

对比看到:

  1. ViewHolder 的编写规范化,ListView 是需要自己定义的,而RecyclerView是规范好的;
  2. RecyclerView复用item全部搞定,不需要想ListView那样setTag()与getTag();
  3. RecyclerView多了一些LayoutManager工作,但实现了布局效果多样化;

1.布局效果

  1. ListView 的布局比较单一,只有一个纵向效果;
  2. RecyclerView 的布局效果丰富, 可以在 LayoutMananger 中设置:线性布局(纵向,横向),表格布局,瀑布流布局
  3. 在RecyclerView 中,如果存在的 LayoutManager 不能满足需求,可以自定义 LayoutManager

2. Item 点击事件

  1. RecyclerView不支持 item 点击事件,只能用回调接口来设置点击事件
  2. ListView的 item 点击事件直接是setOnItemClickListener

3.局部刷新

  1. 在ListView中通常刷新数据是用notifyDataSetChanged() ,但是这种刷新数据是全局刷新的(每个item的数据都会重新加载一遍),这样一来就会非常消耗资源;
  2. RecyclerView中可以实现局部刷新,例如:notifyItemChanged();
  3. 如果要在ListView实现局部刷新,依然是可以实现的,当一个item数据刷新时,我们可以在Adapter中,实现一个notifyItemChanged()方法,在方法里面通过这个 item 的 position,刷新这个item的数据

4.缓存区别

  1. 层级不同

ListView有两级缓存,在屏幕与非屏幕内。mActivityViews + mScrapViews

RecyclerView比ListView多两级缓存:支持开发者自定义缓存处理逻辑,RecyclerViewPool(缓存池)。并且支持多个离屏ItemView缓存(缓存屏幕外2个 itemView)。 mAttachedScrap + mCacheViews + mViewCacheExtension + mRecyclerPool

  1. 缓存内容不同

ListView缓存View。 RecyclerView缓存RecyclerView.ViewHolder

  1. RV优势

a.mCacheViews的使用,可以做到屏幕外的列表项ItemView进入屏幕内时也无须bindView快速重用;

b.mRecyclerPool可以供多个RecyclerView共同使用,在特定场景下,如viewpaper+多个列表页下有优势.

客观来说,RecyclerView在特定场景下对ListView的缓存机制做了补强和完善。

5.动画效果

  1. 在RecyclerView中,已经封装好API来实现自己的动画效果;并且如果我们需要实现自己的动画效果,我们可以通过相应的接口实现自定义的动画效果(RecyclerView.ItemAnimator类),然后调用RecyclerView.setItemAnimator() (默认的有SimpleItemAnimator与DefaultItemAnimator);
  2. 但是ListView并没有实现动画效果,但我们可以在Adapter自己实现item的动画效果;

6.嵌套滚动机制

暂时没看

总结

上面只是总结LV与RV的一些差异,而在实际场景中,我们应该根据自己的需求来选择。

如一些列表页展示,需要动画,或频繁更新,局部刷新,建议用 RV,其功能强大,易于扩展。