RecyclerView是Android 5.0之后推出的在support-v7包里的新控件,是一个可以在有限的视图中展示大量数据集的控件。具体使用的用法如下:
LinearLayoutManager manager = new LinearLayoutManager(SetActivity.this);
mRecycleView.setLayoutManager(manager);
mAdatper = new MyAdatper(mDatalist);
mRecycleView.setAdapter(mAdatper);
//使用系统自带的itemDecoration,V7包里面的
mRecycleView.addItemDecoration(new DividerItemDecoration(SetActivity.this,manager.getOrientation()));
mRecycleView.setItemAnimator(new DefaultItemAnimator()); //使用默认的系统动画
一、LayoutManager与RecyclerView.Adapter
1、RecyclerView.LayoutManager,作为负责Item视图的布局显示管理器,设置Item View在RecyclerView中的位置布局,以及其显示或隐藏,当 Item View重用或者回收的时候,LayoutManger都会向Adapter来请求新的数据来替换原来数据的内容。这种回收重用的机制避免初始化布局,频繁的调用findViewById方法而大大提高了性能;RecyclerView提供了三种内置的LayoutManager:
①LinearLayoutManager:线性布局,横向或者纵向滑动列表
②GridLayoutManager:表格布局
③StaggeredGridLayoutManager:流式布局, 瀑布流效果
2、RecyclerView.Adapter ,主要用来托管数据集合,将数据与布局Item进行绑定
class MyAdatper extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.sample_list_item, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
}
@Override
public int getItemCount() {
return mDatalist.size();
}
}
RecyclerView.Adapter 把Item View视图的创建和数据绑定分开进行管理,onCreateViewHolder()方法为每个Item View inflater出一个View,然后把View直接封装在ViewHolder返回,onBindViewHolder()方法将数据与ViewHolder绑定到一起,而 getItemCount()方法就是返回总共有多少条目。
二、RecyclerView.ItemDecoration 其可以是绘图或者布局,主要用于突出显示,可视化分组边界,来区分适配器中与数据集绑定的Item View。
public static abstract class ItemDecoration {
/**
* Draw any appropriate decorations into the Canvas supplied to the RecyclerView.
* Any content drawn by this method will be drawn before the item views are drawn,
* and will thus appear underneath 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 onDraw(Canvas c, RecyclerView parent, State state) {
onDraw(c, parent);
}
/**
* 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) {
onDrawOver(c, parent);
}
/**
* Retrieve any offsets for the given item. Each field of <code>outRect</code> specifies
* the number of pixels that the item view should be inset by, similar to padding or margin.
* The default implementation sets the bounds of outRect to 0 and returns.
*
* <p>
* If this ItemDecoration does not affect the positioning of item views, it should set
* all four fields of <code>outRect</code> (left, top, right, bottom) to zero
* before returning.
*
* <p>
* If you need to access Adapter for additional data, you can call
* {@link RecyclerView#getChildAdapterPosition(View)} to get the adapter position of the
* View.
*
* @param outRect Rect to receive the output.
* @param view The child view to decorate
* @param parent RecyclerView this ItemDecoration is decorating
* @param state The current state of RecyclerView.
*/
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {
getItemOffsets(outRect, ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition(),
parent);
}
}
RecyclerView在进行绘制的时候会进行绘制Decoration,那么会去调用onDraw()和onDrawOver()方法,那么这边我们其实只要去重写onDraw()或onDrawOver()和getItemOffsets()这两个方法就可以实现, 然后LayoutManager会进行Item布局的时候,回去调用getItemOffsets()方法来计算每个Item的Decoration合适的尺寸。
三、RecyclerView.ItemAnimator 这是一个抽象类,此类定义了对适配器进行更改时,Item上发生的动画效果,默认情况下,RecyclerView使用DefaultItemAnimator,并使用setItemAnimator()方法来设置,当然也可以对ViewHolder通过实现ItemAnimator的子类来实现自定义动画。
这里更新数据集不是用adapter.notifyDataSetChanged()而是
notifyItemInserted(position)与notifyItemRemoved(position) ,否则没有动画效果。notifyItemInserted(position)是在第pos位置插入一条数据的时候回调此方法更新,其调用后有插入的动画。而notifyDataSetChanged()就跟ListView的Adapter方法一样,就是更新整个Adapter中的数据集。说到这里,RecyclerView还有notifyItemChanged(position)方法,当pos位置的数据发生了改变,就会回调此方法,同时调用Adapter中的onBinderViewHolder()方法;