RecyclerView简介
RecyclerView是Android5.0提出的UI控件,通常用来代替传统的ListView。
其官方给出的定义如下:
A flexible view for providing a limited window into a large data set.
释义:灵活的视图提供一个有限的窗口变成一个大数据集。
从定义可以明白,Flexible(可扩展性) 是RecyclerView 显著的特点。
在使用RecyclerView的时候,需要在项目的build.gradle 中添加相应依赖库:
compile 'com.android.support:recyclerview-v7:24.2.1'
ListVIew 与 RecyclerView 的简单对比
- 相同点:
- 由于子布局是被ListView(RecyclerView)所包裹着,所以在获取子布局文件的View对象的时候必须调用
View view = LayoutInflater.from(getContext()).inflate(resourceId,parent,flase);
- 需要自定义 Adapter (适配器)来对所需要的显示的数据进行处理。并借由此适配器,把数据按需求的显示到RecylerView 。
- 优缺点对比:
- ListView 相比 RecyclerView 优点:
- 拥有addHeaderView(),addFooterView()添加头视图和尾视图。
- 通过“android:divider”设置自定义分割线。
- 拥有setOnItemClickListener() 和 setOnItemLongClickListener()设置点击事件和长按事件。
借由以上的这些方法,在RecyclerView 都没有直接可用的接口,所以再实现以上功能的时候,运用ListView比较合适。
- RecyclerView 的优点
- 默认实现View 的复用,不需要类似的If(convertView == null) 的判断实现前提。
- 回收机制更加完善。
- 默认支持局部刷新。
- 容易实现添加Item,删除Item的动画效果
- 容易实现拖拽、侧滑删除等功能。
- 区别之一:
- RecyclerView 将 ListView 中的 getView()功能拆分成了onCreateViewHolder() 和 onBinViewHolder()
RecyclerView 的 Adapter 实现相对于 ListView 繁琐,所以RecyclerView适合运用于,每个子布局是复杂的综合布局的情形。
而相对的若是显示的子布局为简单的TextVIew或ImagView布局,则使用ListView会更简单,高效。
RecyclerView 的四大组成
- Adapter : 为 Item 提供数据
- Layout Manager : Item 的布局
- 布局形式:
-
LayoutManager
:默认为纵向布局 -
LayoutManager.HORIZONTAL
:横向布局 -
StaggeredGridLayoutManager
:瀑布流布局
• Item Animator:添加、删除 Item 动画
• Item Decoration : Item 之间的 Divider(间隔线)
RecyclerView 的简单实现
- 创建 Adapter(适配器) :
- 主要功能是为了 RecyclerView 提供数据 ,简单的实现如下:
创建一个继承RecyclerView.Adapter < DataAdapter.ViewHolder>的 Adapter 类,(其中的ViewHolder是DataAdapter的一个内部实现类)
static class ViewHolder extends RecyclerView.ViewHolder - 创建ViewHolder 内部实现类:让该内部类继承RecyclerView.ViewHolder,具体实现细则与ListView中的ViewHolder一样。
- 创建父布局缓存对象,子布局各个控件的空对象;借由重写ViewHolder方法,利用传入的父布局对象itemView,给各个控件的空对象加载实际的内容:
public ViewHolder(View itemView) {
super(itemView);
//用来保存子项最外层布局的实例
DataView = itemView;
//取Image和Text View的ID 进行实例化对象。
DataImage = (ImageView) itemView.findViewById(R.id.image);
DataName = (TextView) itemView.findViewById(R.id.name);
}
(Data作为数据储存类,存放你想显示的数据)
- 在 DataAdapter 中需要实现以下三个方法
DataAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
:用于映射Item Layout ID,并创建ViewHolder对象进行返回,还可以添加点击事件的处理。void onBindViewHolder(WeatherAdapter.ViewHolder holder, int position)
:为holder设置指定数据(即为所选定的子布局中的Item设置希望显示的参数)-
int getItemCount()
:返回加入Item的个数,等同一个计数器。
- 基本的Adapter实现实例参考如下:
public class DataAdapter extends RecyclerView.Adapter< WeatherAdapter.ViewHolder > {
private List<Data> mDataList;
static class ViewHolder extends RecyclerView.ViewHolder {
View DataView;
ImageView DataImage;
TextView DataName;
public ViewHolder(View itemView) {
super(itemView);
//用来保存子项最外层布局的实例
DataView = itemView;
//取Image和Text View的ID 进行实例化对象。
DataImage = (ImageView) itemView.findViewById(R.id.image);
DataName = (TextView) itemView.findViewById(R.id.name);
}
}
public DataAdapter(List<Data> DataList) {
mDataList = DataList;
}
@Override
public DataAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
/**
* 用inflate加载自定义的视图 weather_itme布局文件,也称为layout的映射
*三个参数的含义:
* 1.想要扩展的布局的资源ID
* 2.将作为扩展布局父项的ViewGroup
* 3.指示是否应该在扩展期间将扩展布局附加至root的布尔值
*/
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.itme, parent, false);
//创建布局缓存对象,最后返回
final ViewHolder holder = new ViewHolder(view);
return holder;
}
/**
* 对RecyclerView子项的数据进行复制,会在每个子项被滚动到屏幕内的时候执行
* 再将数据设置到ViewHolder的IMageView和TextView当中
* @param holder ViewHolder的实例
* @param position 用于得到当前项的Weather实例
*/
@Override
public void onBindViewHolder(DataAdapter.ViewHolder holder, int position) {
Data data = mDataList.get(position);
holder.DataImage.setImageResource(data.getImageId());
holder.DataName.setText(data.getName());
}
/**
*
* @return 返回RecyclerView一共有多少子项,直接返回数据源的长度
*/
@Override
public int getItemCount() {
return mDataList.size();
}
}
RecyclerView 点击事件的实现
- 实现思路:
- (通常把点击事件设置在Adapter的onCreateViewHolder 方法中,使得在刚加载数据的时候就实现了子Item的点击事件)
- 获取包裹子Item的父布局View对象。
- 利用 View 对象对子Item中所需要设置点击事件的控件实例添加设置点击监听。
- 在监听事件中,实现OnClick(View view)对点击事件的具体操作。
- 简单的实现形式可参照下:
//给父布局整个布局设计点击事件
holder.weatherView.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
int position = holder.getAdapterPosition();
//判断其点击的是哪一个模块 返回它的的下标
weather Weather = mWeatherList.get(position);
//通过返回的下标,取到其名称
Toast.makeText(view.getContext(), "you clicker view " + Weather.getName(), Toast.LENGTH_SHORT).show();
}
});
//给父布局中的子控件ImageView 设置点击事件
holder.weatherImage.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
int position = holder.getAdapterPosition();
weather Weather = mWeatherList.get(position);
Toast.makeText(view.getContext(), "you clicker image " + Weather.getName(), Toast.LENGTH_SHORT).show();
}
});
参考资料
- http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2017/0116/7039.html
- http://www.jianshu.com/p/dedbae8ffca1