概述
RecyclerView
是一个 ViewGroup
,它用于渲染任何基于适配器的 View
。它被官方定义为 ListView
和 GridView
的取代者,是在 Support V7
包中引入的。使用该组件的一个理由是:它有一个更易于扩展的框架,尤其是它提供了横向和纵向两个方向滚动的能力。当数据集合根据用户的操作或网络状态的变化而变化时,你很需要这个控件。
要使用 RecyclerView
,需要以下的几个元素:
RecyclerView.Adapter
LayoutManager
ItemAnimator
RecyclerView 项目结构:
此处,当 RecyclerView
添加或移除列表项时,它还提供了动画支持,动画操作在当前的实现下,是非常困难的事情。并且,ViewHolder
在 RecyclerView
中被深度集成,不再只是一个推荐方式。
与 ListView 的对比
因为以下几个理由,RecyclerView
与它的前辈 ListView
是不相同的:
- 适配器中需要 ViewHolder :
ListView
中,要提升性能,你可以不实现ViewHolder
,可以尝试其它的选择;但是在RecyclerView
的适配器中,ViewHolder
是必须要使用的。 - 自定义列表项布局 :
ListView
只能把列表项以线性垂直的方式进行安排,并且不能自定义;RecyclerView
的RecyclerView.LayoutManager
类,可以让任何列表项在水平方向排列,或是以交错的网格模式排列。 - 简单的列表项动画 :关于添加或移除列表项的操作,
ListView
并没有添加任何的规定;对于RecyclerView
来说,它有一个RecyclerView.ItemAnimator
类,可以用来处理列表项的动画。 - 手动的数据源 :对于不同类型的数据源来说,
ListView
有着不同的适配器与之对应,例如ArrayAdapter
,CursorAdapter
。与此相反,RecyclerAdapter
需要开发者自己实现提供给适配器的数据。 - 手动的列表项装饰 :
ListView
有android:divider
属性,用于设置列表项之间的分隔。与此相反,要给RecyclerView
设置分隔线的装饰,需要手动使用RecyclerView.ItemDecoration
对象。 - 手动监测点击事件 :
ListView
为列表上的每个列表项的点击事件都使用AdapterView.OnItemClickListener
接口进行了绑定。与之不同的是,RecyclerView
只提供了RecyclerView.OnItemTouchListener
接口,它可以管理单个的touch
事件,而不再内嵌点击事件的处理
RecyclerView 的组件
LayoutManager
LayoutManager
用于在 RecyclerView
中管理列表项的位置,对于不再对用户可见的视图来说,它还能决定什么时候重用这些视图。
RecyclerView
提供了以下几种内嵌的布局管理器:
LinearLayoutManager
GridLayoutManager
:在网格中显示列表项StaggeredGridLayoutManager
:在交错的网格中显示列表项
继承 RecyclerView.LayoutManager
就可以创建自定义的布局管理器。
RecyclerView.Adapter
RecyclerView
包含一种新的适配器,它与你之前使用过的适配器很类似,只是包含了一些特殊之处,例如必须的 ViewHolder
等。要使用这些适配器,需要重写两个方法:1. 用于渲染视图和 ViewHolder
的方法;2. 用于把数据绑定到视图的方法。每当需要创建一个新的视图时,都会调用第一个方法,不再需要检测视图是否被回收。
ItemAnimator
RecyclerView.ItemAnimator
将会使要通知适配器的 ViewGroup
的改变(例如添加/删除/选择列表项)动起来。DefaultItemAnimator
可以用于基本的默认动画,并且表现不俗。
使用步骤
一、导包
注意:引入V7的包才能使用RecyclerView控件
二、主布局文件代码
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 xmlns:tools="http://schemas.android.com/tools"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 tools:context="com.example.testrecycleview.MainActivity"
6 android:orientation="vertical"
7 >
8
9 <Button
10 android:id="@+id/button1"
11 android:layout_width="wrap_content"
12 android:layout_height="wrap_content"
13 android:layout_alignParentLeft="true"
14 android:layout_alignParentTop="true"
15 android:layout_marginLeft="22dp"
16 android:layout_marginTop="14dp"
17 android:text="Button" />
18
19 <android.support.v7.widget.RecyclerView
20 android:id="@+id/id_recyclerview"
21 android:layout_width="match_parent"
22 android:layout_height="match_parent"
23 android:divider="#ffff0000"
24 android:dividerHeight="10dp" >
25 </android.support.v7.widget.RecyclerView>
26
27 </LinearLayout>
activity_main.xml
三、RecyclerView子Item的布局文件
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 android:orientation="horizontal" >
6
7 <TextView
8 android:id="@+id/tv_username"
9 android:layout_width="wrap_content"
10 android:layout_height="wrap_content"
11 android:text="TextView"
12 android:textSize="25sp"
13 />
14
15 <TextView
16 android:id="@+id/tv_sex"
17 android:layout_width="wrap_content"
18 android:layout_height="wrap_content"
19 android:text="TextView"
20 android:textSize="15sp"
21 />
22
23 <ImageView
24 android:id="@+id/imageView1"
25 android:layout_width="wrap_content"
26 android:layout_height="wrap_content"
27 android:src="@drawable/ic_launcher" />
28
29 </LinearLayout>
item_layout.xml
四、MainActivity.java代码
1 package com.example.testrecycleview;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import android.app.Activity;
7 import android.os.Bundle;
8 import android.support.v7.widget.LinearLayoutManager;
9 import android.support.v7.widget.RecyclerView;
10 import android.support.v7.widget.RecyclerView.Adapter;
11 import android.support.v7.widget.RecyclerView.ItemDecoration;
12 import android.support.v7.widget.RecyclerView.ViewHolder;
13 import android.view.LayoutInflater;
14 import android.view.View;
15 import android.view.View.OnClickListener;
16 import android.view.ViewGroup;
17 import android.widget.Button;
18 import android.widget.ImageView;
19 import android.widget.TextView;
20 import android.widget.Toast;
21
22
23 public class MainActivity extends Activity {
24
25 private RecyclerView recyclerView;
26 private List<User> userList;
27 private Button btn;
28
29 @Override
30 protected void onCreate(Bundle savedInstanceState) {
31 super.onCreate(savedInstanceState);
32 setContentView(R.layout.activity_main);
33
34 userList = new ArrayList<User>();
35 for (int i = 0; i < 8; i++) {
36 User user = new User();
37 user.setUsername("小明"+i);
38 user.setSex("男"+i);
39 userList.add(user);
40 }
41
42 recyclerView = (RecyclerView)findViewById(R.id.id_recyclerview);
43 recyclerView.setLayoutManager(new LinearLayoutManager(this));
44 recyclerView.setAdapter(new MyAdapter());
45 recyclerView.addItemDecoration(new ItemDecoration() {
46 });
47
48 btn = (Button) findViewById(R.id.button1);
49 btn.setOnClickListener(new OnClickListener() {
50
51 @Override
52 public void onClick(View v) {
53
54 User u = new User();
55 u.setUsername("小红红");
56 u.setSex("人妖");
57 userList.add(u);
58 Toast.makeText(MainActivity.this, "ok", 500).show();
59 }
60 });
61
62
63 User u2 = new User();
64 u2.setUsername("小红红2");
65 u2.setSex("人妖2");
66 userList.add(u2);
67 }
68
69 class MyAdapter extends Adapter<MyHolder>{
70
71 @Override
72 public int getItemCount() {
73 return userList.size();
74 }
75
76 @Override
77 public void onBindViewHolder(MyHolder holder, int index) {
78 holder.tv_username.setText( userList.get(index).getUsername() );
79 holder.tv_sex.setText( userList.get(index).getSex() );
80 }
81
82 @Override
83 public MyHolder onCreateViewHolder(ViewGroup arg0, int arg1) {
84 LayoutInflater inflater = getLayoutInflater();
85 //布局文件
86 View view = inflater.inflate(R.layout.item_layout, arg0,false);
87 //控件完全体
88 MyHolder holder = new MyHolder(view);
89 return holder;
90 }
91
92 }
93
94 /*
95 * 控件的完全体
96 */
97 class MyHolder extends ViewHolder{
98 TextView tv_username;
99 TextView tv_sex;
100 ImageView imageView1;
101
102 public MyHolder(View sup) {
103 super(sup);
104 tv_username = (TextView)sup.findViewById(R.id.tv_username);
105 tv_sex = (TextView)sup.findViewById(R.id.tv_sex);
106 imageView1 = (ImageView)sup.findViewById(R.id.imageView1);
107 }
108
109 }
110
111 }
MainActivity
运行结果