RecyclerView和ListView的对比分析

1、布局效果对比
Android 默认提供的 RecyclerView 就能支持 线性布局、网格布局、瀑布流布局 三种(这里我们暂且不提代码细节,后文再说),而且同时还能够控制横向还是纵向滚动。

2、API 使用对比
ListView 的基础使用大家再熟悉不过,其使用的关键点主要如下:

A、继承重写 BaseAdapter 类;
B、自定义 ViewHolder 和 convertView 一起完成复用优化工作;
C、由于 ListView 已经老生常谈,所以此处就不去写示例代码了。 

RecyclerView 基础使用关键点同样有两点:

A、继承重写 RecyclerView.Adapter 和 RecyclerView.ViewHolder;      
B、设置布局管理器,控制布局效果

明显可以看出,RecyclerView 相比 ListView 在使用上的区别主要有如下几点:

A、ViewHolder 的编写规范化了;       
B 、RecyclerView 需要多出一步 LayoutManager 的设置工作
C、RecyclerView 复用 Item 的工作 Google 全帮你搞定,不再需要像 ListView 那样自己调用 setTag

布局效果:RecyclerView 能够支持多种布局效果,核心关键在于RecyclerView.LayoutManager 类,这个LayoutManager就是我们控制RecyclerView 最终的展示效果的。LayoutManager 只是一个抽象类而已,系统已经为我们提供了三个相关的实现类 LinearLayoutManager(线性布局效果)、GridLayoutManager(网格布局效果)、StaggeredGridLayoutManager(瀑布流布局效果)。如果你想用 RecyclerView 来实现自己 YY 出来的一种效果,则应该去继承实现自己的 LayoutManager,并重写相应的方法

3、空数据处理
ListView 提供了setEmptyView 这个 API 来让我们处理 Adapter中数据为空的情况,只需轻轻一 set就能搞定一切。 RecyclerView并没有提供此类 API,所以这些工作需要自己来干。

4、HeaderView 和 FooterView
在 ListView中,存在着 HeaderView 和 FooterView 两种视图,使用 HeaderView 和 FooterView 的好处在于,当我们往 ListView 的头部或者底部添加一个 View 时可以不用影响到 Adapter 的编写,使用起来相当方便。在 RecyclerView 中则没有直接给其添加HeaderView和FooterView的方法,需要我们自己搞定,这里推荐鸿洋大神的大作:优雅的为RecyclerView添加HeaderView和FooterView。

5、局部刷新
在 ListView 中,数据变化后可以调用notifyDataSetChanged() 刷新界面,但是并没有提供局部刷新某个 Item 的 API。调用notifyDataSetChanged() 刷新好处就是调用简单,坏处就是它会重绘每个 Item,但实际上并不是每个 Item 都需要重绘。RecyclerView.Adapter 则为我们提供了 notifyItemChanged 用于更新单个 Item View 的刷新,我们可以省去自己写局部更新的工作。

6、动画效果
ListView的更新动画需要我们自定义。而RecyclerView在做局部刷新的时候有一个渐变的动画效果。RecyclerView 则为我们提供了很多动画 API,其中提供了两个自带的动画实现:SimpleItemAnimator和DefaultItemAnimator。默认调用DefaultItemAnimator。我们也可以通过相应接口自定义动画——继承RecyclerView.ItemAnimator 类,实现相应的方法,再调用 RecyclerView 的 setItemAnimator(RecyclerView.ItemAnimator animator)设置完即可实现自定义的动画。这里为大家介绍一款RecyclerView 的开源动画库:recyclerview-animators。其内部封装了大量的动画效果给供我们调用。

7、滑动和删除
ItemTouchHelper 是系统为我们提供的一个用于滑动和删除 RecyclerView 条目的工具类,用起来非常简单的,大致两步:

A、创建 ItemTouchHelper 实例,同时实现 ItemTouchHelper.SimpleCallback 中的抽象方法,用于初始化 ItemTouchHelper;
B、调用 ItemTouchHelper 的 attachToRecyclerView 方法关联上 RecyclerView 即可。代码大致如下:

//ItemTouchHelper 用于实现 RecyclerView Item 拖曳效果的类

ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
    @Override 
    public int getMovementFlags(RecyclerView recyclerView,  RecyclerView.ViewHolder viewHolder) { 
        //actionState : action状态类型,有三类 ACTION_STATE_DRAG (拖曳),ACTION_STATE_SWIPE(滑动),ACTION_STATE_IDLE(静止) 
        int dragFlags = makeFlag(ItemTouchHelper.ACTION_STATE_DRAG, ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);  //支持上下左右的拖曳 
        int swipeFlags = makeMovementFlags(ItemTouchHelper.ACTION_STATE_SWIPE, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);   //表示支持左右的滑动 
        return makeMovementFlags(dragFlags, swipeFlags);//直接返回0表示不支持拖曳和滑动 
} 
    @Override 
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { 
        int fromPosition = viewHolder.getAdapterPosition();//要拖曳的位置 
        int toPosition = target.getAdapterPosition();//要放置的目标位置 
        Collections.swap(mData, fromPosition, toPosition); //做数据的交换 
        notifyItemMoved(fromPosition, toPosition);
        return true; 
    } 
    @Override 
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { 
        int position = viewHolder.getAdapterPosition();//获取要滑动删除的Item位置 
        mData.remove(position); //删除数据 
        notifyItemRemoved(position); 
    } 
}); 
itemTouchHelper.attachToRecyclerView(mRecyclerView);

8、监听 Item 的事件
ListView 为我们准备了几个专门用于监听 Item 的回调接口,如单击、长按、选中某个 Item 等。大家对他们的使用应该都是游刃有余,这里不多说。RecyclerView并没有像 ListView 提供太多关于 Item 的监听,唯一的就是 addOnItemTouchListener,API 的名字言简意赅,就是监听 Item 的触摸事件。如果你想要拥有 ListView 那样监听某个 Item 的某个操作方法,可以看看这篇文章:RecyclerView无法添加onItemClickListener的高效解决方案;

9、嵌套滚动机制
熟悉 Android 触摸事件分发机制的童鞋肯定知道,Touch 事件在进行分发的时候,由父 View 向它的子 View 传递,一旦某个子 View 开始接收进行处理,那么接下来所有事件都将由这个 View 来进行处理,它的 ViewGroup 将不会再接收到这些事件,直到下一次手指按下。而嵌套滚动机制(NestedScrolling)就是为了弥补这一机制的不足,为了让子 View 能和父 View 同时处理一个 Touch 事件。关于嵌套滚动机制(NestedScrolling),实现上相对是比较复杂的,此处就不去拓展说明,其关键在于 NestedScrollingChildNestedScrollingParent 两个接口,以及系统对这两个接口的实现类 NestedScrollingChildHelperNestedScrollingParentHelper 大家可以查阅相关的资料。 Android 官方提供的 MaterialDesign 设计风格的控件配合RecyclerView可以实现一系列炫酷的效果同时有效避免嵌套滑动冲突

你可能感兴趣的:(原创)