如今越来越多的开发者开始使用RecyclerView,与传统的ListView相比,它有许多优势:有更多的布局方式,更好的动画效果,更加灵活容易扩展,有局部刷新的能力等等。但不是说这样就能而完全取代ListView,毕竟它添加分割线、Header和Footer十分方便,而且自带有item的点击事件。所以使用RecyclerView还是ListView还是看具体应用场景。
RecyclerView之ItemDecoration
在RecyclerView中,没有divider
属性来添加分割线;所以在开发中,RecyclerView使用这个类ItemDecoration来添加分割线,如下:
...
ItemDecoration decoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL);
recyclerView.addItemDecoration(decoration);
...
但它的能力远非如此,话不多说,先看两个效果:
要实现这样的效果只需要继承RecyclerView的ItemDecoration,重写它里面的方法就好了。先看一下ItemDecoration的源码,有下面三个方法:
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state)
/**
* Draw any appropriate decorations into the Canvas supplied to the RecyclerView.
* Any content drawn by this method will be drawn after the item views are drawn
* and will thus appear over the views.
*
* @param c Canvas to draw into
* @param parent RecyclerView this ItemDecoration is drawing into
* @param state The current state of RecyclerView.
*/
public void onDrawOver(Canvas c, RecyclerView parent, State state)
/**
* Draw any appropriate decorations into the Canvas supplied to the RecyclerView.
* Any content drawn by this method will be drawn after the item views are drawn
* and will thus appear over the views.
*
* @param c Canvas to draw into
* @param parent RecyclerView this ItemDecoration is drawing into
* @param state The current state of RecyclerView.
*/
public void onDrawOver(Canvas c, RecyclerView parent, State state)
OutRect
在讲上述三个方法前,先了解一下什么是OutRect
。
OutRect
就是每个itemview下的矩形区域,默认情况下,outRect
的left、top、right和bottom的值为0;itemview和OutRect是重合,就只能看见itemview。所以函数:
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state)
的作用就是把OutRect
撑开一定的区域,就可以使用onDraw()
和onDrawOver()
在这些被撑开的区域进行绘画。
RecyclerView的背景、onDraw
绘制的内容、Item
、onDrawOver
绘制的内容,各层级关系如下1:
也就是说,onDraw绘制的内容可能会被itemView遮挡,itemView也可能被onDrawOver绘制的内容遮挡。
分割线
我们想给RecyclerView添加分割线,**思路是把每个itemView的顶部或底部撑开一定的宽度,注意到在主布局中背景色设置为黑色,itemView的背景色在item_view.xml中设置为白色。那么当itemView顶部或底部撑开一段距离后,背景色就露了出来,看上去就像一条条的分割线。**废话少说,开始动手写吧。我们创建一个新项目,添加RecyclerView的依赖后,在MainActivity中添加一个RecyclerView,布局文件为:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:orientation="vertical"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
然后我们来写RecyclerView 的适配器。先定义一个itemVIew 的布局,命名为item_view,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff"
android:elevation="5dp">
<TextView
android:id="@+id/tv_item"
android:text="35sp"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="70dp" />
</LinearLayout>
我们只是演示一下效果,就简单定义一个TextView就好了。Adapter的代码如下:
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<String> mList;
private Context context;
public MyAdapter(List<String> list, Context context