Android在Android L中推出了RecyclerView来代替ListView呈现列表类的数据,RecyclerView相比于ListView使用起来更加的灵活,可自定义的内容也更多。下面用一个例子来介绍一下RecyclerView的具体用法
RecyclerView位于support v7包中,使用之前需要添加依赖,在AndroidStudio中通过快捷键ctrl+shift+alt+s打开projectstructure界面,然后选中对应的module,再点击右边的tab切换到Dependencies界面,点击加号选择Library Dependency,找到RecyclerView点击OK即可。
和ListView 相似,想要使用RecyclerView也必须先实现一个适配器来适配数据。新建一个class文件使其继承自RecyclerView.Adapter。RecyclerView.Adapter需要一个继承自RecyclerView.ViewHolder的ViewHolder类,我们先写RecyclerView.ViewHolder然后为我们的Adapter添加未实现的方法。刚创建好的Adapter如下所示。
public class MyRecycleAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return null;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
}
@Override
public int getItemCount() {
return 0;
}
}
下面我们来实现ViewHolder类,直接写成Adapter中的静态内部类即可:
public static class MyViewHolder extends RecyclerView.ViewHolder{
public MyViewHolder(View itemView) {
super(itemView);
}
}
创建好后别忘了将Adapter中的ViewHolder类型改成我们自定义的MyViewHolder:
public class MyRecycleAdapter extends RecyclerView.Adapter<MyRecycleAdapter.MyViewHolder> {
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return null;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
}
@Override
public int getItemCount() {
return 0;
}
public static class MyViewHolder extends RecyclerView.ViewHolder{
public MyViewHolder(View itemView) {
super(itemView);
}
}
}
下面我们来实现Adapter和ViewHolder中的方法。首先需要建立一个item布局来作为每个列表项的布局。item布局我们使用一个线性布局包裹的TextView:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content">
<TextView android:id="@+id/tv_name" android:padding="16dp" android:minHeight="45dp" android:gravity="center_vertical" android:text="hello" android:layout_width="match_parent" android:layout_height="wrap_content"/>
</LinearLayout>
创建好布局后,回到Adapter类中,在onCreateViewHolder方法中通过布局解析器解析item布局:
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item,parent,false);
布局解析完毕后实例化一个MyViewHolder对象,构造方法中传入itemView布局。
MyViewHolder viewHolder = new MyViewHolder(itemView);
将viewHolder作为返回值返回。
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item, parent, false);
MyViewHolder viewHolder = new MyViewHolder(itemView);
return viewHolder;
}
onCreateViewHolder实现完毕。
下面回到MyViewHolder中,声明一个成员变量TextView tvName,即我们的item布局中的TextView。在构造方法中通过itemView来绑定TextView:
public static class MyViewHolder extends RecyclerView.ViewHolder{
TextView tvName;
public MyViewHolder(View itemView) {
super(itemView);
tvName = (TextView) itemView.findViewById(R.id.tv_name);
}
}
下面回到Adapter类中实现onBindViewHolder方法。
我们用一个String数组来作为示例数据,在getItemCount()方法中返回数组的长度。onBindViewHolder中通过传入的position参数获得对应的数据:String str = mStrings[position]
然后为TextView设置文字:holder.tvName.setText(str);
至此,Adapter就自定义完成了。
在MainActivity中声明一个Adapter对象:
private MyRecyclerAdapter mAdapter = new MyRecyclerAdapter();
在onCreateView
中绑定布局中的RecyclerView
通过LayoutManager
来设置item项的排列方式,LayoutManager
共有三个子类:
1、LinearLayoutManager
线性列表布局
2、GridLayoutManger
表格列表布局
3、StaggeredGridLayoutManager
瀑布流布局
这里我们使用LinearLayoutManager
RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recycler_view);
LinearLayoutManager layoutMagener = new LinearLayouManager(MainActivity.this);
recyclerView.setLayoutManager(layoutMagener);
//然后为recyclerView设置adapter后就可以将数据呈现在列表里了
recyclerView.setAdapter(mAdapter);
不同于ListView,RecyclerView并没有提供setOnItemClickListener的方法,因此我们不能直接为item设置监听,需要我们自己动手来实现:如何实现呢?我们可以为每个itemView添加点击监听,然后在RecyclerAdapter中通过添加我们自己的接口来实现在Activity中回调,下面我们来看代码:
1.首先在onCreateViewHolder中解析完itemView 的布局后,为itemView 设置点击监听,另外还需要在onBindViewHolder时,为viewHolder的itemView设置tag,方便在点击到itemView时将数据传出:
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item, parent, false);
//让Adapter类实现监听
itemView.setOnClickListener(this);
MyViewHolder viewHolder = new MyViewHolder(itemView);
return viewHolder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.tvName.setText(mStrings[position]);
holder.itemView.setTag(mStrings[position]);
}
2.然后再向Adapter类中创建一个item点击的接口回调和设置监听的方法
public interface OnItemClickListener{
//将itemView中的tag里的数据传出
void onItemClick(String nameStr);
}
private OnItemClickListener mListener;
public void setOnItemClickListener(OnItemClickListener listener){
mListener = listener;
}
最后在itemView的onClick(View v);方法中调用接口中的方法即可:
@Override
public void onClick(View v) {
if (mListener != null) {
//传入的v对象即是我们点击的itemView
mListener.onItemClick((String) v.getTag());
}
}
想要实现监听,我们只需要在Activity中为adapter添加我们自定义的回调即可:
mAdapter.setOnItemClcikListener(this);
@Override
public void onItemClick(String name) {
//在这里做相关的操作
Toast.makeText(this,"点击到的item中的内容为" + name,Toast.LENGTH_SHORT).show();
}
至此RecyclerView就实现完毕了,可以看到,相比ListView,RecyclerView 的灵活性体现在它将数据和布局的排列方式分离开来,更方便管理和自定义。以后就让我们彻底的抛弃ListView吧。