RecyclerView 是Android L版本中新添加的一个用来取代ListView的SDK,它的灵活性与可替代性比listview更好。接下来通过一系列的文章讲解如何使用RecyclerView,彻底抛弃ListView(如有不周,纯属谬论)。
首先gradle引入依赖库,列表的每一个Item我这使用的是CardView所以还需引入CardView库
compile 'com.android.support:design:23.4.0'
compile 'com.android.support:cardview-v7:23.4.0'
- 布局声明
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
- 先添加一些测试数据,方便测试
private void initData() {
list = new ArrayList<>();
for (int i = 1; i <= 50; i++) {
CellData cellData = new CellData("我是标题" + i, "我是内容" + i);
list.add(cellData);
}
}
- RecyclerView跟ListView不同的一点就是需要我们为其指定布局管理器,用来确定每一个item如何进行排列摆放,何时展示和隐藏。
目前SDK中提供了三种自带的LayoutManager:
1.LinearLayoutManager
2.GridLayoutManager
3.StaggeredGridLayoutManager
//线性布局,第一个参数不用说,第二个容器的走向,第三个时候反转意思就是以中间为对称轴左右两边互换。
LinearLayoutManager manager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
//网格布局,第一个参数不用说,第二个容器的行数和列数,第三个容器走向,第四个同上。
GridLayoutManager manager = new GridLayoutManager(this, 6, GridLayoutManager.HORIZONTAL, false);
//为RecyclerView设置LayoutManger
mRecyclerView.setLayoutManager(manager);
//设置item固定大小
mRecyclerView.setHasFixedSize(true);
- 设置适配器和数据
MyAdapter mAdapter = new MyAdapter(list);
mRecyclerView.setAdapter(mAdapter);
- 我们都知道ListView需要我们去写一个ViewHolder用来管理视图,同样RecyclerView也需要一个ViewHolder,不过这里源码已经帮我我们定义好了我们只需要写一个自己的类来继承RecyclerView.ViewHolder就可以了
//视图管理者
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView title, content;
private View root;
public ViewHolder(View root) {
super(root);
this.root = root;
title = (TextView) root.findViewById(R.id.tv_title);
content = (TextView) root.findViewById(R.id.tv_content);
}
}
1.继承RecyclerView.Adapter<MyAdapter.ViewHolder>
这里Adapter需要一个ViewHolder,就给我们自定义的就ok了。
需要实现的方法
//返回Item条数
@Override
public int getItemCount() {
return list.size();
}
//创建视图管理者,初始化我们的列表Item布局,这里同时还设置了列表的点击和长按事件。
//因为官方没有为我们写好这两个事件,所以需要我们自定义了。
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View root = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_success, parent, false);
ViewHolder vh = new ViewHolder(root);
//为Item设置点击事件,以整个item作为可点击的对象
root.setOnClickListener(this);
root.setOnLongClickListener(this);
return vh;
}
//绑定视图管理者
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.title.setText(list.get(position).getTitle());
holder.content.setText(list.get(position).getContent());
//设置Tag,方便等下进行点击事件数据的处理
holder.root.setTag(position);
}
接下来就为我们的Item设置点击事件了,需要我们自己定义两个接口来实现
//点击事件
public interface RecyclerViewOnItemClickListener {
void onItemClickListener(View view, int position);
}
//长按事件
public interface RecyclerViewOnItemLongClickListener {
boolean onItemLongClickListener(View view, int position);
}
- 放上整个Adapter代码,这样看起来就更清晰一些。
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>
implements View.OnClickListener, View.OnLongClickListener {
private List<CellData> list;
public MyAdapter(List<CellData> list) {
this.list = list;
}
private RecyclerViewOnItemClickListener onItemClickListener;
private RecyclerViewOnItemLongClickListener onItemLongClickListener;
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView title, content;
private View root;
public ViewHolder(View root) {
super(root);
this.root = root;
title = (TextView) root.findViewById(R.id.tv_title);
content = (TextView) root.findViewById(R.id.tv_content);
}
}
@Override
public int getItemCount() {
return list.size();
}
//绑定视图管理者
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.title.setText(list.get(position).getTitle());
//设置Tag
holder.content.setText(list.get(position).getContent());
holder.root.setTag(position);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View root = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_success, parent, false);
ViewHolder vh = new ViewHolder(root);
//为Item设置点击事件
root.setOnClickListener(this);
root.setOnLongClickListener(this);
return vh;
}
@Override
public void onClick(View v) {
if (onItemClickListener != null) {
//注意这里使用getTag方法获取数据
onItemClickListener.onItemClickListener(v, (Integer) v.getTag());
}
}
@Override
public boolean onLongClick(View v) {
return onItemLongClickListener != null && onItemLongClickListener.onItemLongClickListener(v, (Integer) v.getTag());
}
/*设置点击事件*/
public void setRecyclerViewOnItemClickListener(RecyclerViewOnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
/*设置长按事件*/
public void setOnItemLongClickListener(RecyclerViewOnItemLongClickListener onItemLongClickListener) {
this.onItemLongClickListener = onItemLongClickListener;
}
public interface RecyclerViewOnItemClickListener {
void onItemClickListener(View view, int position);
}
public interface RecyclerViewOnItemLongClickListener {
boolean onItemLongClickListener(View view, int position);
}
}
然后就是MainActivity对这两个事件的监听了
//设置RecyclerView的每一项的点击事件
mAdapter.setRecyclerViewOnItemClickListener(new MyAdapter.RecyclerViewOnItemClickListener() {
@Override
public void onItemClickListener(View view, int position) {
Snackbar.make(view, "点击事件:" + list.get(position).getContent(), Snackbar.LENGTH_SHORT).show();
}
});
//设置RecyclerView的每一项的长按事件
mAdapter.setOnItemLongClickListener(new MyAdapter.RecyclerViewOnItemLongClickListener() {
@Override
public boolean onItemLongClickListener(View view, int position) {
Snackbar.make(view, "长按事件:" + list.get(position).getContent(), Snackbar.LENGTH_SHORT).show();
return true;
}
});
瞄一下Item布局,这里面就用到了CardView了,可以让你的app看起来更加美观,待会看下效果图。
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginBottom="@dimen/activity_vertical_margin"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:layout_marginTop="@dimen/activity_vertical_margin"
card_view:cardBackgroundColor="#fffefe"
card_view:cardCornerRadius="10dp"
card_view:contentPadding="5dp">
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/tv_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginTop="50dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#364b37" />
</android.support.v7.widget.CardView>