RecyclerView简单介绍
RecyclerView是一个高度的解耦,异常的灵活的View,通过设置它提供的不同LayoutManager,ItemDecoration , ItemAnimator实现令人瞠目的效果。
RecyclerView与老前辈ListView的不同点,主要在于以下几个特性:
Adapter中的ViewHolder模式 对于ListView来说,通过创建 ViewHolder 来提升性能并不是必须的。因为ListView并没有严格的ViewHolder设计模式。但是在使用RecyclerView的时候,Adapter 必须实现至少一个ViewHolder,必须遵循ViewHolder设计模式。
定制Item条目 ListView只能实现垂直线性排列的列表视图,与之不同的是,RecyclerView可以通过设置RecyclerView.LayoutManager来定制不同风格的视图,比如水平滚动列表或者不规则的瀑布流列表。
tem动画 在ListView中没有提供任何方法或者接口,方便开发者实现Item的增删动画。相反地,可以通过设置RecyclerView的 RecyclerView.ItemAnimator 来为条目增加动画效果。
设置数据源 在LisView中针对不同数据封装了各种类型的 Adapter ,比如用来处理数组的 ArrayAdapter 和用来展示Database结果的 CursorAdapter 。相反地,在RecyclerView中必须自定义实现 RecyclerView.Adapter 并为其提供数据集合。
设置条目分割线 在ListView中可以通过设置 android:divider 属性来为两个Item间设置分割线。如果想为RecyclerView添加此效果,则必须使用 RecyclerView.ItemDecoration ,这种实现方式不仅更灵活,而且样式也更加丰富。
设置点击事件 在ListView中存在 AdapterView.OnItemClickListener 接口,用来绑定条目的点击事件。但是,很遗憾的是在RecyclerView中,并没有提供这样的接口,不过,提供了另外一个接口 RcyclerView.OnItemTouchListener ,用来响应条目的触摸事件。
RecyclerView简单使用
一个是在Gradle中直接添加:
compile 'com.android.support:recyclerview-v7:24.2.1'
版本号不用找,仿照上面的appcompat直接用,把appcompat改成recyclerview即可
compile 'com.android.support:appcompat-v7:24.2.1'
第二种是在Design面板直接拖拽,会提示你添加
核心类的介绍
RecyclerView的任务仅限于回收和定位屏幕上的View。 View能够显示数据还离不
开另外两个类的支持:Adapter子类和ViewHolder子类。
RecyclerView.Adapter 处理数据集合并负责绑定视图
ViewHolder 持有所有的用于绑定数据或者需要操作的View
LayoutManager 负责摆放视图等相关操作
ItemDecoration 负责绘制Item附近的分割线
ItemAnimator 为Item的一般操作添加动画效果,如,增删条目等
ViewHolder
ViewHolder只做一件事:容纳View视图
RecyclerView自身不会创建视图,它创建的是ViewHolder,而ViewHolder引用着一个个
itemView,如下图:
可以通过打印 ViewHolder.toString 来获取更多有效信息
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("ViewHolder{" +
Integer.toHexString(hashCode()) + " position=" + mPosition + " id=" + mItemId +
", oldPos=" + mOldPosition + ", pLpos:" + mPreLayoutPosition);
if (isScrap()) {
sb.append(" scrap ")
.append(mInChangeScrap ? "[changeScrap]" : "[attachedScrap]");
}
if (isInvalid()) sb.append(" invalid");
if (!isBound()) sb.append(" unbound");
if (needsUpdate()) sb.append(" update");
if (isRemoved()) sb.append(" removed");
if (shouldIgnore()) sb.append(" ignored");
if (isTmpDetached()) sb.append(" tmpDetached");
if (!isRecyclable()) sb.append(" not recyclable(" + mIsRecyclableCount + ")");
if (isAdapterPositionUnknown()) sb.append(" undefined adapter position");
if (itemView.getParent() == null) sb.append(" no parent");
sb.append("}");
return sb.toString();
}
Adapter
Adapter是个控制器对象,从模型层获取数据,然后提供给RecyclerView显示,起到了沟通的桥梁作用,adapter负责:
1、创建必要的ViewHolder;
2、 绑定ViewHolder至模型层数据。
public VH onCreateViewHolder(ViewGroup parent, int viewType) 创建Item视图,并返回相应的ViewHolder
public void onBindViewHolder(VH holder, int position) 绑定数据到正确的Item视图上。
public int getItemCount() 返回该Adapter所持有的Itme数量
要创建adapter, 首先要定义RecyclerView.Adapter子类,RecyclerView需要显示视图对象时, 就会去找它的adapter,如下图:
首先,通过调用adapter的getItemCount()方法,RecyclerView询问数组列表中包含多少个
对象。
接 着 , RecyclerView 调 用 adapter 的 createViewHolder(ViewGroup, int) 方 法 创 建
ViewHolder以及ViewHolder要显示的视图。
最后, RecyclerView会传入ViewHolder及其位置, 调用onBindViewHolder(ViewHolder,
int)方法。adapter会找到目标位置的数据并绑定到ViewHolder的视图上。所谓绑定,就是使用
模型数据填充视图。
整个过程执行完毕,RecyclerView就能在屏幕上显示crime列表项了。需要注意的是,相对
于onBindViewHolder(ViewHolder, int)方法,createViewHolder(ViewGroup, int)方法
的调用并不频繁。一旦创建了够用的ViewHolder,RecyclerView就会停止调用createView
Holder(…)方法。然后,通过回收利用旧的ViewHolder节约时间和内存。
开始使用
首先创建一个JavaBean负责模拟数据
public class JavaBean {
String name;
int age;
public JavaBean(String name, int age) {
this.name = name;
this.age = age;
}
}
然后在根据上面的两种方式添加依赖,之后设置控制器:
/**
* @author HaoTianYi hao.ty@haotianyi.win
* @version v1.0
* @des 一个作用是初始化UI、一个是负责更新数据
* @time 2016-11-10 18:54
*/
public class MyHolder extends RecyclerView.ViewHolder {
private TextView mTvAge;
private TextView mTvName;
public MyHolder(View itemView) {
super(itemView);
// 初始化View
mTvAge = (TextView) itemView.findViewById(R.id.age);
mTvName = (TextView) itemView.findViewById(R.id.name);
}
/**
* 负责更新数据也就是刷新UI
* @param bean 数据
* @call 由MyAdapter的onBindViewHolder方法调用
*/
public void bindData(JavaBean bean) {
mTvAge.setText(" "+bean.age);
mTvName.setText(bean.name);
}
}
设置内容填充者:
/**
* @author HaoTianYi hao.ty@haotianyi.win
* @version v1.0
* @des 从模型层拿到数据并且传递给RecyclerView(中间人的角色)
* @time 2016-11-10 18:54
*/
public class MyAdapter extends RecyclerView.Adapter<MyHolder> {
private List<JavaBean> mBeen;
public MyAdapter(List<JavaBean> been) {
mBeen = been;
}
@Override
public MyHolder