参考:https://developer.android.com/training/material/lists-cards.html
1、简介
RecyclerView已经出现了很长一段时间了,伴随着Material Design也就是Android L的出现而出现,它的灵活性比ListView更好。和ListView一样:它也是一个用于显示庞大数据集的容器,可通过保持有限数量的视图进行非常有效的滚动操作。
那么既然有了ListView,为啥还需要RecyclerView呢?
首先看一下RecyclerView的结构:
整体上看RecyclerView的结构,其提供了拔插式的体验,高度的解耦,异常的灵活。
RecyclerView通过提供以下功能简化庞大数据集的显示和处理:
1、通过布局管理器LayoutManager控制其显示方式。
2、通过ItemDecoration控制Item间的间隔。
3、通过ItemAnimator控制Item增删的动画。
4、当然,点击事件需要自己手动处理。
2、基本使用
(1)RecyclerView的使用主要分为以下几步:
/**
* init the RecyclerViews
*/
private void initRecyclerViews() {
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
// 用于提升性能
mRecyclerView.setHasFixedSize(true);
// 设置布局
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
//设置适配器
List<String> myDataset = new ArrayList<String>();
for (int i = 0; i < 100; i++) {
myDataset.add("data" + i);
}
mAdapter = new MyAdapter(myDataset);
mRecyclerView.setAdapter(mAdapter);
//设置Item增加、移除动画
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
}
1、设置布局管理器。目前SDK中自带三种LayoutManager,分别是:LinearLayoutManager、GridLayoutManager、
StaggeredGridLayoutManager,其中StaggeredGridLayoutManager可以实现瀑布流的效果。
也就是说:使用一个RecyclerView就可以实现ListView、GridView的效果,是不是很方便!
2、设置适配器。这个适配器需要继承自RecyclerView.Adapter,如下所示。在MyAdapter里面有一个内部类ViewHolder,这个类继承自RecyclerView.ViewHolder,相当于RecyclerView规范了ViewHolder的写法。然后在onCreateViewHolder里面返回自定义的ViewHolder。在onBindViewHolder方法里面设置ViewHolder里面的控件的相关属性。
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private List<String> mDataset;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView mTextView;
public ViewHolder(View v) {
super(v);
mTextView = (TextView) v.findViewById(R.id.tv_item);
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(List<String> myDataset) {
mDataset = myDataset;
}
// Create new views (invoked by the layout manager)
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.activity_list_item, parent, false);
// set the view's size, margins, paddings and layout parameters
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
holder.mTextView.setText(mDataset.get(position));
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return mDataset.size();
}
}
3、设置Item增加、移除动画,这个是可以自定义的。
4、设置Item间的分割线,这个也是可以自定义的。
(2)MainActivity布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/myCoordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:logo="@android:drawable/ic_dialog_dialer"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:subtitle="sub Title"
app:title="Title" />
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
(3)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="wrap_content"
android:padding="10dp"
android:gravity="center">
<TextView
android:id="@+id/tv_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp" />
</LinearLayout>
(4)MainActivity代码:
package com.easyliu.recyclerviewdemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
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.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initRecyclerViews();
}
/**
* init the RecyclerViews
*/
private void initRecyclerViews() {
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
// 用于提升性能
mRecyclerView.setHasFixedSize(true);
// 设置布局
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
//设置适配器
List<String> myDataset = new ArrayList<String>();
for (int i = 0; i < 100; i++) {
myDataset.add("data" + i);
}
mAdapter = new MyAdapter(myDataset);
mRecyclerView.setAdapter(mAdapter);
//设置Item增加、移除动画
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
}
}
效果如下:
以上就是RecyclerView的基本使用过程,使用的是LinearLayoutManager。
3、高级使用
(1)给Item添加点击事件
我们发现为RecyclerView的每一项添加点击事件并没有ListView那么容易,像ListView直接添加个onItemClickListener即可。这时候,接口就派上用场了!
1、定义一个接口:
public interface IOnListItemClickListener {
public void onClick(int position);
public void onLongClick(int position);
}
2、在自定义的Adapter当中添加设置接口的方法:
private IOnListItemClickListener mIOnListItemClickListener;
public void setOnListItemClickListener(IOnListItemClickListener iOnListItemClickListener) {
this.mIOnListItemClickListener = iOnListItemClickListener;
}
3、在OnBindViewHolder方法当中给当前的View设置监听:
//设置监听
holder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mIOnListItemClickListener!=null){
mIOnListItemClickListener.onClick(position);
}
}
});
holder.mView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
if (mIOnListItemClickListener!=null){
mIOnListItemClickListener.onLongClick(position);
return true;
}
return false;
}
});
当然,需要注意的是,这里的ViewHolder改了,改成了如下所示,也就是把传进去的View保存了起来,然后在上面的方法当中获取。
public static class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView mTextView;
public View mView;
public ViewHolder(View v) {
super(v);
mView=v;
mTextView = (TextView) v.findViewById(R.id.tv_item);
}
}
4、在MainActivity当中实现这个接口:
mAdapter.setOnListItemClickListener(new IOnListItemClickListener() {
@Override
public void onClick(int position) {
Snackbar.make(getWindow().getDecorView(), "onClick" + position, Snackbar.LENGTH_SHORT).show();
}
@Override
public void onLongClick(int position) {
Snackbar.make(getWindow().getDecorView(), "onLongClick" + position, Snackbar.LENGTH_SHORT).show();
}
});
以上就是给RecyclerView的item添加点击事件的基本过程。
(2)添加和删除数据:
1、在自定义的Adapter当中添加如下两个方法,主要是调用了RecyclerView的notifyItemInserted和notifyItemRemoved这两个方法。
/**
* 添加数据
* @param position
*/
public void addData(int position,String data) {
mDataset.add(position,data);
notifyItemInserted(position);
}
/**
* 删除数据
* @param position
*/
public void removeData(int position) {
mDataset.remove(position);
notifyItemRemoved(position);
}
2、使用
给Toolbar添加两个菜单:add和delete,然后在onOptionsItemSelected方法当中根据ID执行相应的操作:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.list_add:
mAdapter.addData(1, "add");
return true;
case R.id.list_delete:
mAdapter.removeData(1);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
记住,需要给RecyclerView设置动画,不然没有动画效果。
效果如下:
以上只是讲了RecyclerView的基本使用方法,其深入的知识还包括:
1、LayoutManager的使用和自定义
2、ItemDecoration的使用和自定义
3、ItemAnimator的使用和自定义
下次再讲~~~~
代码下载地址:https://github.com/EasyLiu-Ly/MaterialDesignDemos