RecyclerView是Android5.0新加入的用于替代ListView的UI控件,该控件与适配器Adapter、数据源DataSet的关系如下图所示:
![这里写图片描述](https://img-blog.csdn.net/20160118151026866)
RecyclerView的特性
相比于ListView,RecyclerView多了一个LayoutManager,Adapter也有所不同,下面将RecyclerView的新特性罗列如下:
- 必须指定Adapter和LayoutManager;
- 1、需要继承类RecyclerView.Adapter,重写下列方法:
- onCreateViewHolder(ViewGroup parent, int viewType);
- onBindViewHolder(ViewHolder holder, int position);
- getItemCount();
- 2、三种内置的LayoutManager
- LinearLayoutManager;
- GridLayoutManager;
- StaggeredGridLayoutManager;
- 必须使用ViewHolder模式,以便复用每一个Item;
- 简化了大量数据的显示和处理;
- 1、提供了LayoutManager,用于定位Item Views,用于决定何时重用不再可见的Item Views;
- 2、提供了默认的动画,用于Items的添加和删除等操作;
- 可以自定义LayoutManager和动画;
- 1、继承类RecyclerView.LayoutManager;
- 2、继承类RecyclerView.ItemAnimator,重写方法RecyclerView.setItemAnimator();
在Eclipse中配置并使用RecyclerView
在Android官方文档中仅介绍了如何在Android Studio使用RecyclerView,并没有介绍如何在Eclipse中使用,其具体配置方法与同样是在Android5.0版本中引入的系统控件CardView相仿,具体步骤请参阅我的博文《在Eclipse中配置并使用UI控件CardView》。
XML布局
整体布局
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" >
</android.support.v7.widget.RecyclerView>
注意:RecyclerView需使用全限定类名。
每个Item的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="8dp" >
<TextView
android:id="@+id/textview_1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:textColor="@android:color/holo_green_dark"
android:textSize="21sp" />
<TextView
android:id="@+id/textview_2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:textColor="@android:color/holo_orange_light"
android:textSize="15sp" />
</LinearLayout>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
每个Item纵向布置了两个TextView。
定义DataSet
为了给每个Item装入数据,应定义一个类存放相应数据:
package com.test.recyclerview_test2;
public class ItemObject {
private String mText_1;
public String getText_1() {
return mText_1;
}
public ItemObject(String text_1, String text_2) {
super();
mText_1 = text_1;
mText_2 = text_2;
}
public ItemObject() {
super();
}
public void setText_1(String text_1) {
mText_1 = text_1;
}
public String getText_2() {
return mText_2;
}
public void setText_2(String text_2) {
mText_2 = text_2;
}
private String mText_2;
}
- 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
- 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
定义Adapter
继承RecyclerView.Adapter,并重写该类中的3个方法;由于RecyclerView要求必须定义ViewHolder,故还需要在定义的Adapter中定义一个继承了RecyclerView.ViewHolder的内部类。具体代码示例如下所示:
public class CustomRecyclerViewAdapter extends
Adapter<CustomRecyclerViewAdapter.MyViewHolder> {
private ItemObject[] mItemObjects;
private Context mContext;
public CustomRecyclerViewAdapter(ItemObject[] itemObjects, Context context) {
super();
mItemObjects = itemObjects;
mContext = context;
}
public CustomRecyclerViewAdapter() {
super();
}
public static class MyViewHolder extends ViewHolder {
private TextView mTextView_1;
private TextView mTextView_2;
public MyViewHolder(View view) {
super(view);
mTextView_1 = (TextView) view.findViewById(R.id.textview_1);
mTextView_2 = (TextView) view.findViewById(R.id.textview_2);
}
}
@Override
public int getItemCount() {
return mItemObjects.length;
}
@Override
public void onBindViewHolder(MyViewHolder myViewHolder, int position) {
myViewHolder.mTextView_1.setText(mItemObjects[position].getText_1());
myViewHolder.mTextView_2.setText(mItemObjects[position].getText_2());
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup arg0, int arg1) {
View _view = LayoutInflater.from(mContext).inflate(R.layout.item, arg0,
false);
MyViewHolder _myViewHolder = new MyViewHolder(_view);
return _myViewHolder;
}
}
- 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
- 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
activity逻辑实现
与ListView相仿,设置RecyclerView为如下步骤:
- 设置数据源;
- 创建LayoutManager,为RecyclerView设置LayoutManager;
- 绑定数据源和Adapter;
- 为RecyclerView设置Adapter;
可见,设置RecyclerView比ListView多了第二步,就是设置LayoutManager。
具体示例代码如下:
public class MainActivity extends Activity {
private RecyclerView mRecyclerView;
private LayoutManager mLayoutManager;
private CustomRecyclerViewAdapter mCustomRecyclerViewAdapter;
private ItemObject[] mItemObjects = new ItemObject[100];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
for (int i = 0; i < mItemObjects.length; ++i) {
ItemObject _itemObject = new ItemObject();
_itemObject.setText_1("Title Of Item No." + (i + 1));
_itemObject.setText_2("Content Of Item No." + (i + 1));
mItemObjects[i] = _itemObject;
}
mCustomRecyclerViewAdapter = new CustomRecyclerViewAdapter(
mItemObjects, this);
mRecyclerView.setAdapter(mCustomRecyclerViewAdapter);
}
}
- 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
- 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
demo的实现效果
![这里写图片描述](https://img-blog.csdn.net/20160118161601189)
![这里写图片描述](https://img-blog.csdn.net/20160118161502968)
![这里写图片描述](https://img-blog.csdn.net/20160118161635060)
在Android Studio中引入RecyclerView
在Android Studio中引入RecyclerView比在Eclipse中简单得多,而且方法有两种:
- 在Gradle脚本的build.gradle文件中的dependencies中加入
compile 'com.android.support:recyclerview-v7:23.+'
即可。 - File–>Project Structure–>Modules(选择用到RecyclerView的module)–>Dependencies选项卡–>点击右上角”+”号引入
'com.android.support:recyclerview-v7:23.+'
依赖。
RecyclerView的基本用法
要点1:ViewHolder
ViewHolder是RecyclerView的内部类,该内部类要求必须实现,以复用AdapterView中的每一个Item。
public class MyViewHolder extends RecyclerView.ViewHolder{
public TextView mTextView;
public MyViewHolder(View itemView) {
super(itemView);
mTextView = (TextView) itemView.findViewById(android.R.id.text1);
}
}
上述代码中MyViewHolder的构造方法需要传入一个View作为每个Item的布局。
要点2:Adapter
Adapter是RecyclerView的内部类,该内部类需要一个泛型参数ViewHolder,也就是自定义的ViewHolder。
public class MyAdatper extends RecyclerView.Adapter<MyViewHolder> {
private List<PackageInfo> packageInfos;
public MyAdatper(List<PackageInfo> packageInfos) {
this.packageInfos = packageInfos;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
return new MyViewHolder(layoutInflater.inflate(android.R.layout.simple_list_item_1, parent, false));
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
TextView textView = holder.mTextView;
textView.setText(packageInfos.get(position).packageName);
}
@Override
public int getItemCount() {
return packageInfos.size();
}
}
- 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
- 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
要点3:Activity中实现
recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
packageInfoList = getPackageManager().getInstalledPackages(0);
adapter = new MyAdatper(packageInfoList);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
实现效果
![这里写图片描述](https://img-blog.csdn.net/20160130205011945)
RecyclerView进阶
RecyclerView为Item提供了局部的增删改方法
在ListView中,若有Item中的数据需要增删改,可以调用adapter的notifyDataSetChanged方法,通知ListView刷新数据列表。
在RecyclerView中也有同样的方法实现同样的效果。除此之外,RecyclerView中的Adapter还提供了刷新增删改的某一项的方法,这些方法可以实现局部操作,节省内存开销。
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_add) {
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "com.win16.add";
packageInfoList.add(0, packageInfo);
adapter.notifyItemInserted(0);
recyclerView.scrollToPosition(0);
}
else if (id == R.id.action_remove) {
packageInfoList.remove(0);
adapter.notifyItemRemoved(0);
}
else if (id == R.id.action_update) {
packageInfoList.get(0).packageName = "com.win16.update";
adapter.notifyItemChanged(0);
}
else {
adapter.notifyDataSetChanged();
}
return super.onOptionsItemSelected(item);
}
- 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
- 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
效果展示:
![before_add](https://img-blog.csdn.net/20160130205415529)
添加一条数据
![before_remove](https://img-blog.csdn.net/20160130205449155)
删除一条数据
![before_update](https://img-blog.csdn.net/20160130205601963)
修改一条数据
要点4:LayoutManager
LayoutManager是RecyclerView的内部类,该内部类可以灵活定制AdapterView的布局形式:可以是类似于GridView的网格形式——需要new一个GridLayoutManager,可以是普通ListView形式——需要new一个LinearLayoutManager,甚至是瀑布流形式——需要new一个StaggeredGridLayoutManager。
将下面一行:
recyclerView.setLayoutManager(new LinearLayoutManager(this));
替换为:
recyclerView.setLayoutManager(new GridLayoutManager(this,5, GridLayoutManager.HORIZONTAL,false));
将布局改变为GridView的样式,指定为5列(行),横向滑动,效果如下:
GridView样式,横向滑动,5行
或替换为GridView瀑布流样式:
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL))
上述代码是GridView瀑布流样式,布局为3列,纵向布置效果如下:
GridView瀑布流样式(每一项是交错的),2列,纵向布置