在上一篇Blog中已经讲到过了RecyclerVIew的特性等等,现在我们开始正式讲讲这个它吧。
RecyclerView作为listview的更新版面世,有着他得天独厚的优势:
第一点,就是他更完善Recycler机制,比listview的recycler机制还相对完善,可以指定recycler缓冲池中循环利用的view的数量;
第二点,recyclerview不再有由自己来管理子布局view了,全部交给layoutmanger管理;
第三点,完美解决了循环和滚动的问题,而且支持横向布局;
第四点,支持item动画,猿们终于不用自己写很多代码去对item设置动画,懒点可以使用默认动画,想炫点可以自己自定义动画并通过setItemAnimator()方法设置……
好了,不多说,优势还有很多,就让猿们自己慢慢挖掘吧。

recyclerview是21新增的widget,想使用的话,需要使用以下最新的support-v7-21包,以及recyclerview的单独支持包。这两个包都可以在最新的SDK中提取出来,使用jar包或者工程都可以。



导入包后我们就可以开始使用recyclerview了,在布局文件中使用方法如下。Eclipse中是无法找到的,只能自己手动把android.support.v7.widget.RecyclerView打出来,在AS上可以直接找到。

1
2
3
4
5
6
<android.support.v7.widget.RecyclerView
android:id="@+id/rvlist"
android:layout_below="@+id/title_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none" />

布局有了,item的布局我就不说,下面跟随我的步伐看看代码里怎么使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private void showDate() {
// 创建一个线性布局管理器
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
// 设置垂直布局,目前仅支持LinearLayout(有垂直和横向)
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
// 设置缓冲池最大循环使用view数
mRecylerView.getRecycledViewPool().setMaxRecycledViews(0, 10);
// 设置布局管理器
mRecylerView.setLayoutManager(layoutManager);
// 创建Adapter,并指定数据集
mAdapter = new TestAdaper(this, mList);
// 设置Adapter
mRecylerView.setAdapter(mAdapter);
// 设置默认动画
mRecylerView.setItemAnimator(new DefaultItemAnimator());
// 还有下面这上三种动画FlipDownItemAnimator, SlideItemAnimator, FromTopItemAnimator
}

Adapter的变化更是大,recyclerview的adapter使用viewholder,使用时必须继承RecyclerView.Adapter;在listview中,我们使用getview()来获取item的布局,在这里我们必须使用onCreateViewHolder(ViewGroup parent, int viewtype)来获取布局,其中第二个参数viewtype怎么来的?其实是我们传进来的,如果我们需要使用多布局,则必须复写getItemViewType方法,这个方法没有强制必须复写,但是多布局时必须复写,这是个int返回值得方法,我们将你的布局类型传进去,这样我们就可以得到viewtype。另外,viewholder的使用必须继承RecyclerView.ViewHolder。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package com.hjhrq1991.adapter;
import java.util.List;
import com.hjhrq1991.bean.TestInfo;
import com.hjhrq1991.recyclerviewdemo.R;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class TestAdaper extends RecyclerView.Adapter<ViewHolder> {
private List<TestInfo> mList;
private Context context;
public TestAdaper(Context context, List<TestInfo> mList) {
super();
this.context = context;
this.mList = mList;
}
/**
* 内部TextHoler
*/
public class TextHoler extends RecyclerView.ViewHolder {
public TextView textView;
public TextHoler(View view) {
super(view);
}
}
/**
* iamgeHolder
*/
public class ImageHoler extends RecyclerView.ViewHolder {
public TextView textView;
public ImageView Imageview;
public ImageHoler(View view) {
super(view);
this.textView = (TextView) view.findViewById(R.id.text);
this.Imageview = (ImageView) view.findViewById(R.id.image);
}
}
/**
* 按钮的holder
*/
public class CbHoler extends RecyclerView.ViewHolder {
public TextView textView;
public ImageView Imageview;
public CheckBox checkbox;
public CbHoler(View view) {
super(view);
this.textView = (TextView) view.findViewById(R.id.text);
this.Imageview = (ImageView) view.findViewById(R.id.image);
this.checkbox = (CheckBox) view.findViewById(R.id.checkbox);
}
}
@Override
public int getItemCount() {
// TODO Auto-generated method stub
return mList.size();
}
/**
* 获取item的类型
*/
@Override
public int getItemViewType(int position) {
// TODO Auto-generated method stub
return mList.get(position).getType();
}
/**
* 创建view
*/
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewtype) {
// TODO Auto-generated method stub
View v = null;
ViewHolder holer = null;
switch (viewtype) {
case TestInfo.TASK_TEXT:
v = LayoutInflater.from(parent.getContext()).inflate(
R.layout.item_text_layout, null);
holer = new TextHoler(v);
break;
case TestInfo.TASK_DRAWABLE:
v = LayoutInflater.from(parent.getContext()).inflate(
R.layout.item_image_layout, null);
holer = new ImageHoler(v);
break;
case TestInfo.TASK_CHEXKBOX:
v = LayoutInflater.from(parent.getContext()).inflate(
R.layout.item_checkbox_layout, null);
holer = new CbHoler(v);
break;
}
return holer;
}
/**
* 在这里进行数据的绑定,参数1是onCreateViewHolder创建的viewholder,参数2是你item的位置
*/
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
// TODO Auto-generated method stub
switch (getItemViewType(position)) {
case TestInfo.TASK_TEXT:
TextHoler textholer = (TextHoler) holder;
textholer.textView.setText(mList.get(position).getContent());
break;
case TestInfo.TASK_DRAWABLE:
ImageHoler imageHolder = (ImageHoler) holder;
imageHolder.textView.setText(mList.get(position).getContent());
imageHolder.Imageview.setImageResource(mList.get(position)
.getDrawableurl());
break;
case TestInfo.TASK_CHEXKBOX:
CbHoler cbHoler = (CbHoler) holder;
cbHoler.textView.setText(mList.get(position).getContent());
cbHoler.Imageview.setImageResource(mList.get(position)
.getDrawableurl());
cbHoler.checkbox.setText(mList.get(position).getCbcontent());
break;
}
}
}

看了这么多代码,估计猿们纷纷表示,click方法呢?怎么没见到onitemclick方法?是的,listview里有onItemClick方法,但是这样容易造成item和item内部控件的点击事件冲突,为了解决这个问题,recyclerview不再提供onitemclick方法。惊恐纳尼,不提供,那怎么破?别担心,onitemclick方法可以在adapter中实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
* item点击事件的实现
*/
class OnItemClick implements View.OnClickListener {
public OnItemClick() {
}
@Override
public void onClick(View v) {
Toast.makeText(context, "你点击了item", Toast.LENGTH_SHORT).show();
}
}
/**
* item内部控件点击事件的实现
*/
class OnClick implements View.OnClickListener {
private int position;
public OnClick(int position) {
this.position = position;
}
@Override
public void onClick(View v) {
Toast.makeText(context, "你点击了第" + position + "个text",
Toast.LENGTH_SHORT).show();
}
}

onItemClick方法在ViewHolder里使用

1
2
3
4
5
6
7
8
9
public class TextHoler extends RecyclerView.ViewHolder {
public TextView textView;
public TextHoler(View view) {
super(view);
this.textView = (TextView) view.findViewById(R.id.text);
view.setOnClickListener(new OnItemClick());// 这里使用onItemClick方法
}
}

至于item内部控件的点击事件在onBindViewHolder方法里实现。
除了这种方法可以实现onItemClick事件外,还有其他方法,例如在复写recyclerview源码,扩展他的点击事件方法。我自己还有另一种方法,在adapter里写一个接口,在activity里实现接口并监听接口,这种方法就在我下一篇blog使用recyclerview实现Gallery画廊效果里说吧。



demo下载