RecyclerView的使用
第一次写博客,而且还是第一次用MarkDown,排版可能很渣
引用一段从优快云里原话:
那么有了ListView、GridView为什么还需要RecyclerView这样的控件呢?整体上看RecyclerView架构,提供了一种插拔式的体验,高度的解耦,异常的灵活,通过设置它提供的不同LayoutManager,ItemDecoration , ItemAnimator实现令人瞠目的效果。
*使用它需要在Gradle的组件配置文件里添加
compile 'com.android.support:recycleview-v7:25.3.1'
RecyclerView使用时的三个主要对象:
-RecyclerView
-RecyclerView.Adapter
-RecyclerView.ViewHolder
RecyclerView用于回收和定位Item,Adapter用于将数据和视图绑定,ViewHolder用于容纳Item的View。
我的理解是,RecyclerView是一个管理很多个View的”大容器“,而ViewHolder就是这个“大容器”的一个个“小隔间”,用来容纳“View”(注意:ViewHolder的数量只有屏幕上显示的View的数量+2);Adapter存储有View的数据,它就像一个“花名册”记录着所有在RecyclerView中的View的数据。
1. RecyclerView使用方法
- 新建RecyclerView对象
RecycerView listview = (RecycerView)findViewById(R.id.recycerview);
- 为RecyclerView对象设置LayoutManager
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
listview.setLayoutManager(layoutManager);
- 为RecyclerView对象设置adapter
MyAdapter adapter = new MyAdapter(list);
listview.setAdapter(adapter);
- RecycerView的另外的一些方法
mRecyclerView = findView(R.id.id_recyclerview);
//设置布局管理器
mRecyclerView.setLayoutManager(layout);
//设置adapter
mRecyclerView.setAdapter(adapter)
//设置Item增加、移除动画
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
//添加分割线
mRecyclerView.addItemDecoration(new DividerItemDecoration(
getActivity(), DividerItemDecoration.HORIZONTAL_LIST));
2. RecyclerView的Adapter
Adapter用于将数据(List)和视图(一般是Holder)绑定。所以Adapter首先要维护一个数据的集合,例如ArrayList
- 新建Adapter类继承自RecyclerView.Adapter
public class MyAdapter extends RecycerView.Adapter<MyAdapter.ViewHolder>{
//使用内部类MyAdapter.ViewHolder
ArrayList<String> list;
public MyAdapter(ArrayList<String> list)
{
this.list = list;
}
//内部类: ViewHolder
protected final class ViewHolder extends RecycerView.ViewHolder{
//RecyclerView强制规定,adapter的泛型制定为holder
//将会在Adapter之后介绍holder
TextView tView;
public ViewHolder(View view)
{
super(view);
this.tView = view.findViewById(R.id.textview);
}
}
}
- MyAdapter需要实现以下抽象方法
-ViewHolder onCreateViewHolder()
-void onBindViewHolder()
-int getItemCount()
其与RecyclerView的关系如下所述:
RecyclerView要视图时,就会去找它的Adapter:
1)先调用Adapter的getItemCount()方法,询问数组列表中的对象数量。
2)RecyclerView调用adapter的createViewHolder(ViewGroup,int)方法创建ViewHolder以及ViewHolder要显示的视图。
3)RecyclerView会传入ViewHolder及其位置,调用onBindViewHolder(ViewGroup,int)方法。adapter会找到目标位置的数据并且绑定到ViewHolder视图上。绑定就是使用模型数据填充视图。
三个过程ok后,RecyclerView就能在屏幕上显示View了,另外createViewHolder以及onBindViewHolder使用并并不频繁。创建了够用的ViewHolder就停止调用了。然后会自动回收旧的ViewHolder来节约时间和节省内存。
public class MyAdapter extends RecycerView.Adapter<MyAdHolder.ViewHolder>{
ArrayList<String> list;
public MyAdapter(ArrayList<String> list)
{
this.list = list;
}
protected final class ViewHolder extends RecycerView.ViewHolder{
//RecyclerView强制规定,adapter的泛型指定为holder
//将会在Adapter之后介绍holder
TextView tView
public ViewHolder(View view)
{
this.tView = view;
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
//该方法用于创建ViewHolder,所以应该从这里将View生成并传给ViewHolder
View view = LayoutInflater.from(
parent.getContext()).inflate(R.layout.layout,parent,false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position)
{
//该方法用于将数据和ViewHolder绑定,根据position将List的值赋值给ViewHolder
holder.tView.setText(list.get(position));
}
@Override
public int getItemCount()
{
//该方法用于返回item的个数,一般返回list的长度即可。
return list.size();
}
}
3. RecyclerView的ViewHolder
ViewHolder通过保存item中使用到的控件的引用来减少findViewById的调用,以此使ListView滑动得更加顺畅。可见,一个ViewHolder应该能够接收Adapter传给它的ViewGroup并将其中的每个View实现并“Hold”其实例。
一个典型的ViewHolder如下(假设每个Item由两个TextView和一个ImageView组成):
public class MyHolder extends RecyclerView.ViewHolder{
TextView id, name;
ImageView image;
public MyHolder(View itemView) {
super(itemView);
this.id = (TextView) itemView.findViewById(R.id.item_num);
this.name = (TextView) itemView.findViewById(R.id.item_name);
this.image = (ImageView) itemView.findViewById(R.id.item_image);
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
}
}
生成ViewHolder后,可以直接通过ViewHolder的实例来获取每个Item中的View了,不需要再使用一次findViewById()。
另外还可以让ViewHolder实现事件监听器接口,直接为ViewHolder的View绑定事件。
//注:这里的MyHolder是MyAdapter的内部类
protected final class MyHolder extends RecyclerView.ViewHolder implements View.OnClickListener,View.OnLongClickListener{
TextView id, name;
ImageView image;
public MyHolder(View itemView) {
super(itemView);
this.id = (TextView) itemView.findViewById(R.id.item_num);
this.name = (TextView) itemView.findViewById(R.id.item_name);
this.image = (ImageView) itemView.findViewById(R.id.item_image);
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
}
@Override
public void onClick(View v) {
clickedListener.onItemClicked(v, getPosition());
}
@Override
public boolean onLongClick(View v) {
longClickedListener.onItemLongClicked(v, getPosition());
return true;
}
}
以上是我个人总结的RecyclerView的用法笔记,若有不足还望不吝指正,感谢。
参考资料:
Android L新控件RecyclerView简介
RecyclerView,Adapter和ViewHolder
Android RecyclerView 使用完全解析 体验艺术般的控件
RecyclerView使用介绍
感谢以上文章作者的无私分享。