Google在推出Android5.0的时候推出了Material Design ,而RecyclerView是Material Design 重要组件之一。当然还有CardView/Palette。
RecyclerView是用来替换传统的ListView和GridView,瀑布流效果的。是的RecyclerView这一个控件,可以实现这三个效果。虽然在开始使用recyclerview的时候会感到有些男,但是用熟练了会发现recyclerview十分强大。它可以给每一item里面的控件设置点击时间,而不需要担心事件冲突的问题,如果是使用listview或者是gridview就必须要解决事件冲突,甚至listview或gridview的item只能设置一个点击事件,否则就会造成事件冲突,而这些冲突并不好解决。所以recyclerview来了。
首先在项目中集成RecyclerView,在build.gradle添加RecyclerView的依赖
compile 'com.android.support:recyclerview-v7:23.2.1'
这样项目中就集成 recyclerview了,Android Studio 会自动联网下载 recyclerview包。
在activity_main.xml中,使用recyclerview.
1
2
3
4
|
<
android.support.v7.widget.RecyclerView
android:id
=
"@+id/recyclerView"
android:layout_width
=
"match_parent"
android:layout_height
=
"match_parent"
/>
|
布局中已经有了recyclerview的控件,下面就开始在代码中编写。
在这里解释一下recyclerview的使用。就像listview那样,recyclerview也需要一个适配器;在我们优化listview的时候,我们经常会使用到一个内部类ViewHolder来保存item中的控件,以便于item的复用。而现在recyclerview则必须使用ViewHolder。这个ViewHolder必须继承RecyclerView.ViewHolder,RecyclerView.ViewHolder有一个参数的构造方法,传入的是一个view,这个view 就是recyclerview的item。
RecyclerViewHolder:
1
2
3
4
5
6
7
8
9
|
public
class
RecyclerViewHolder
extends
RecyclerView.ViewHolder {
public
TextView textView;
public
ImageView imageView;
public
RecyclerViewHolder(View itemView) {
super
(itemView);
textView = (TextView) itemView.findViewById(R.id.textView);
imageView = (ImageView) itemView.findViewById(R.id.imageView);
}
}
|
RecyclerViewHolder写好之后就开始写Adapter.同样RecyclerAdapter需要继承RecyclerView.Adapter<RecyclerViewHolder>,泛型ViewHolder就是自己自定义的RecyclerViewHolder。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
31
32
33
34
35
36
|
public
class
RecyclerAdapter
extends
RecyclerView.Adapter<RecyclerViewHolder> {
private
List<Map<String, String>> dataList;
public
RecyclerAdapter() {
dataList =
new
ArrayList<>();
}
public
void
addAll(List<Map<String, String>> data){
dataList.addAll(data);
}
/**
*
* @param viewType 对应的是getItemViewType(int position)方法返回的数值
*/
@Override
public
RecyclerViewHolder onCreateViewHolder(ViewGroup parent,
int
viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent,
false
);
return
new
RecyclerViewHolder(view);
}
/**
*
* @param holder 对应的是onCreateViewHolder方法,返回的RecyclerViewHolder
* @param position 当前的item的位置
*/
@Override
public
void
onBindViewHolder(RecyclerViewHolder holder,
int
position) {
holder.textView.setText(dataList.get(position).get(
"data"
));
}
@Override
public
int
getItemCount() {
return
dataList.size();
}
}
|
MainActivity中的代码。
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
|
public
class
MainActivity
extends
AppCompatActivity {
private
RecyclerView recyclerView;
//使用线性布局管理器,设置的方向orientation是默认,即垂直方向
private
LinearLayoutManager manager;
//适配器
private
RecyclerAdapter adapter;
//数据源
private
List<Map<String, String>> list;
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
manager =
new
LinearLayoutManager(
this
);
adapter =
new
RecyclerAdapter();
//设置布局管理器
recyclerView.setLayoutManager(manager);
//给recyclerview设置适配器
recyclerView.setAdapter(adapter);
list =
new
ArrayList<>();
for
(
int
i=
0
;i<
50
;i++)
{
Map<String,String> map =
new
HashMap<>();
map.put(
"data"
,
"item--> "
+i);
list.add(map);
}
adapter.addAll(list);
adapter.notifyDataSetChanged();
}
}
|
recyclerview实现listview的效果就完成了,运行效果:
如果是想每个item横向滑动的话,只需要使用LinearLayoutManager的三个参数的构造方法就行了,new LInearLayoutManager(this, LinearLayoutManager.HORIZONTAL, true)就可以实现横向滑动的效果了。
recyclerView实现GridView的效果。需要是用是GridLayoutManager。将recyclerView的布局管理器更换成GridLayoutManager manager = new GridLayoutManager(this, 2),效果图如下:
给RecyclerView添加滚动监听。与listView和gridView有写不同,recyclerView判断滚动到哪一个位置的饿时候,需要使用到使用到布局管理器(前面设置的recyclerview.setLayoutManager())。滚动监听的方法有两个,setOnScrollListener(已不推荐使用)和addOnScrollListener。两个方法本质上是一致的。代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
recyclerView_follow.addOnScrollListener(
new
RecyclerView.OnScrollListener() {
@Override
public
void
onScrollStateChanged(RecyclerView recyclerView,
int
newState) {
super
.onScrollStateChanged(recyclerView, newState);
//滚动的状态改变时,调用此方法。
}
@Override
public
void
onScrolled(RecyclerView recyclerView,
int
dx,
int
dy) {
super
.onScrolled(recyclerView, dx, dy);
//屏幕中最下面一个item的所在数据源的位置(postion)。
int
lastVisiableItem = manager.findLastVisibleItemPosition();
//一共有多少个
int
totalItemCount = manager.getItemCount();
//当滑动到倒数第二个item时,即联网获取下一页的数据
if
(lastVisiableItem >= totalItemCount -
2
&& dy >
0
) {
page++;
//第二页
reloadData(page);
}
}
});
|
给RecyclerView添加监听事件:
首先在Adapter中的onBindViewHolder方法中设置点击事件,使用holder.xxx.setOnClickListener()设置点击事件.RecyclerView避免了事件的冲突问题,可以给每个item中的控件设置点击事件.
本文转自 墨宇hz 51CTO博客,原文链接:http://blog.51cto.com/zzhhz/1753676