概述:
RecyclerView是support-v7包中的新组件,是一个强大的滑动组件,与经典的ListView相比,同样拥有item回收复用的功能,但是直接把viewholder的实现封装起来,用户只要实现自己的viewholder就可以了,该组件会自动帮你回收复用每一个item。官方对RecyclerView的描述是:RecyclerView is a more advanced and flexible version of ListView. This widget is a container for large sets of views that can be recycled and scrolled very efficiently. Use the RecyclerView widget when you have lists with elements that change dynamically.简单说,它是ListView的进化,为了当你需要动态展示一组数据的时候就会需要它。
RecyclerView从2014年发布到现在已经很长时间了,使用已经相当普遍。本文主要介绍了RecyclerView的基础使用,后面会陆续写博客和各位一起交流使用RecyclerView自动加载更多数据、加头部尾部、item的拖拽和划动删除、RecyclerView实现多布局等等。
recyclerview相比listview的优点:
- 简介中提到的它封装了viewholder的回收复用。
- RecyclerView使用布局管理器管理子view的位置,也就是说你再不用拘泥于ListView的线性展示方式,能够使用复杂的布局来展示一个动态组件。
- 可以设置加载和移除时的动画,方便做出各种动态浏览的效果
为每个条目位置提供了布局管理器(RecyclerView.setLayoutManager)
RecyclerView提供这些内置的布局管理器:
- LinearLayoutManager(用来)显示垂直或水平滚动的列表项
- GridLayoutManager(用来)显示网格中的item(项)
- StaggeredGridLayoutManager(用来)显示交错的网格item(项目)
为每个条目设置了操作动画(RecyclerView.setItemAnimator)
通过调用如下方法可以设置item加载或移除时的动画:
recyclerView.setItemAnimator(new DefaultItemAnimator());
更多的动画效果可以看别人写的
RecyclerViewItemAnimators这个项目,或者这个第三方库:
https://github.com/wasabeef/recyclerview-animators
RecyclerView的基本使用
使用recyclerview的前期准备
RecyclerView 是 android-support-v7-21 版本中新增的一个 Widgets,除了需要导入v7包之外,还需要导入recyclerview的jar包。gradle里加入:
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:recyclerview-v7:23.1.1'
xml配置:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.recyclerviewdemo.MainActivity">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recycler_view"/>
</LinearLayout>
MainActivity中代码:
package com.recyclerviewdemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private List<String> data;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView= (RecyclerView) findViewById(R.id.recycler_view);
// 创建线性布局管理器(默认是垂直方向)
RecyclerView.LayoutManager manager=new LinearLayoutManager(this);
recyclerView.setLayoutManager(manager);
setDatas();
MyAdapter adapter=new MyAdapter(data);
recyclerView.setAdapter(adapter);
}
private List<String> setDatas() {
data=new ArrayList<>();
for (int i = 0; i < 100; i++) {
data.add("第"+i+"条数据");
}
return data;
}
}
MyAdapter 中代码:
package com.recyclerviewdemo;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.List;
/**
* Created by Michellea on 2016/9/26.
*/
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private List<String> mData;
public MyAdapter(List<String> data) {
this.mData=data;
}
/**
* 用于创建控件
* @param parent
* @param viewType
* @return
*/
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.item,null);
return new ViewHolder(view);
}
/**
* 为控件设置数据
* @param holder
* @param position
*/
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.textView.setText(mData.get(position));
}
@Override
public int getItemCount() {
return mData.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView textView;
public ViewHolder(View itemView) {
super(itemView);
textView= (TextView) itemView.findViewById(R.id.text);
}
}
}
运行结果:
可以看到的问题是每条数据之间的间隔太小,还有就是没有分割线,视觉效果不好,下面介绍下动态设置数据间的间隔和添加分割线。
- 设置item间的间隔:
首先需要定义一个类继承ItemDecoration,代码如下:
package com.recyclerviewdemo;
import android.graphics.Rect;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private List<String> data;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView= (RecyclerView) findViewById(R.id.recycler_view);
// 创建线性布局管理器(默认是垂直方向)
RecyclerView.LayoutManager manager=new LinearLayoutManager(this);
recyclerView.setLayoutManager(manager);
setDatas();
MyAdapter adapter=new MyAdapter(data);
recyclerView.setAdapter(adapter);
MyItemDecoration decor=new MyItemDecoration(50);
recyclerView.addItemDecoration(decor);
}
private List<String> setDatas() {
data=new ArrayList<>();
for (int i = 0; i < 100; i++) {
data.add("第"+i+"条数据");
}
return data;
}
<span style="color:#ff0000;">private class MyItemDecoration extends RecyclerView.ItemDecoration{
private int mSpace;
public MyItemDecoration(int iSpace) {
this.mSpace=iSpace;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
outRect.bottom=mSpace;
outRect.left=mSpace;
}
}</span>
}
- 设置item间的分割线:
compile 'com.yqritc:recyclerview-flexibledivider:1.2.9'
package com.recyclerviewdemo;
import android.graphics.Color;
import android.graphics.Rect;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration;
import com.yqritc.recyclerviewflexibledivider.VerticalDividerItemDecoration;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private List<String> data;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView= (RecyclerView) findViewById(R.id.recycler_view);
// 创建线性布局管理器(默认是垂直方向)
RecyclerView.LayoutManager manager=new LinearLayoutManager(this);
recyclerView.setLayoutManager(manager);
setDatas();
MyAdapter adapter=new MyAdapter(data);
recyclerView.setAdapter(adapter);
MyItemDecoration decor=new MyItemDecoration(50);
recyclerView.addItemDecoration(decor);//添加item间的间距
<span style="color:#ff0000;"> recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(this)
.color(Color.RED).size(1).margin(50,0).build());//添加item间的分割线</span>
}
private List<String> setDatas() {
data=new ArrayList<>();
for (int i = 0; i < 100; i++) {
data.add("第"+i+"条数据");
}
return data;
}
private class MyItemDecoration extends RecyclerView.ItemDecoration{
private int mSpace;
public MyItemDecoration(int iSpace) {
this.mSpace=iSpace;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
outRect.bottom=mSpace;
outRect.top=mSpace;
outRect.left=mSpace;
}
}
}
效果图:
一些细节方面的效果可以按照上面的思路去摸索。
参考资料: