你的位置:首页 > 操作系统

[操作系统]浅谈Android RecyclerView


Android RecyclerView 是Android5.0推出来的,导入support-v7包即可使用。

个人体验来说,RecyclerView绝对是一款功能强大的控件。

首先总结下RecyclerView的特点:

1.支持不同方向,不同排版模式,实现多种展现数据的形式,涵盖了ListView,GridView,瀑布流等数据表现的形式

2.内部实现了回收机制,无需我们考虑View的复用情况

3.取消了onItemClick等点击事件,需要自己手动去写

------------------------------------------------------------------------------------

那么让我们通过一些Demo来了解RecyclerView的基本使用

 

首先,要导入support-v7 包

import android.support.v7.widget.RecyclerView;

RecyclerView和ListView的使用一样,都需要有对应的Adapter,列表项布局,数据源

1.先写主Activity布局

可以看到RecyclerView的标签

<android.support.v7.widget.RecyclerView>

 

 1 <LinearLayout "http://schemas.android.com/apk/res/android" 2        "http://schemas.android.com/tools" "http://schemas.android.com/apk/res-auto" 3        android:layout_width="match_parent" 4        android:layout_height="match_parent" 5        android:orientation="vertical" 6        tools:context="com.xqx.superapp.app.Android5Activity"> 7  8   <Button 9       android:text="添加一个数据"10       android:layout_width="wrap_content"11       android:layout_height="wrap_content"12       android:onClick="btnAddItem"13       />14   <Button15       android:text="删除第一个"16       android:onClick="btnRemoveItem"17       android:layout_width="wrap_content"18       android:layout_height="wrap_content"/>19   20   <android.support.v7.widget.RecyclerView21     android:id="@+id/recycle_view"22     android:layout_width="match_parent"23     android:layout_height="match_parent"24     >25   </android.support.v7.widget.RecyclerView>26 27 </LinearLayout>

 

菜单项布局,标准的上面图片,下面文字

<?"1.0" encoding="utf-8"?><LinearLayout "http://schemas.android.com/apk/res/android"       android:orientation="vertical"       android:gravity="center"       android:layout_width="match_parent"       android:layout_height="match_parent">    <ImageView        android:id="@+id/item_icon"        android:src="@mipmap/machao_moqi"        android:layout_width="wrap_content"        android:layout_height="wrap_content"/>    <TextView        android:id="@+id/item_title"        android:text="名称"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        /></LinearLayout>

 

2.接下来就看Activity代码了

首先看成员变量,与ListView,GridView一样 标准三样, 控件,数据源,适配器

private List<String> data;     private RecyclerView recyclerView;private MyRecycleAdapter adapter;  //自定义适配器,继承RecyclerView.Adapter

 

接着我们必须要自定义一个ViewHolder,这个ViewHolder 必须要继承 RecyclerView.ViewHolder

注意RecyclerView不再提供onItemClick事件监听,所以需要我们自己手工写监听事件的方法

private static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {    public ImageView imageView;    public TextView textView;    public ViewHolder(View itemView) {      super(itemView);      // 通常ViewHolder的构造,就是用于获取控件视图的      imageView = (ImageView) itemView.findViewById(R.id.item_icon);      textView = (TextView) itemView.findViewById(R.id.item_title);      // TODO 后续处理点击事件的操作      itemView.setOnClickListener(this);    }    @Override    public void onClick(View v) {      int position = getAdapterPosition();      Context context = imageView.getContext();      Toast.makeText(context,"显示第"+position+"个项",Toast.LENGTH_SHORT).show();    }  }

 

再让我们看自定义适配器,注意这里的参数是ViewHolder,这个ViewHodler是我们自己的,不要导入v7包下的ViewHolder,

之后要重写三个方法

private class MyRecycleAdapter extends RecyclerView.Adapter<ViewHolder>{
  
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
return null;
}

@Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {

}

@Override
public int getItemCount() {
return 0;
}

}

在自定义适配器MyRecycleAdapter中,首先要写一个构造方法,因为有数据源,所有构造方法里必然有List

private List<String> strings;public MyRecycleAdapter(List<String> strings) {   this.strings = strings;}

然后就要重写三个方法了,

 1 @Override 2 public int getItemCount() { 3   int ret = 0; 4   if (strings != null) { 5     ret = strings.size(); 6    } 7     return ret; 8 } 9 10  @Override11     public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {12       ViewHolder ret = null;13       // 不需要检查是否复用,因为只要进入此方法,必然没有复用14       // 因为RecyclerView 通过Holder检查复用15       View v = LayoutInflater.from(Android5Activity.this).inflate(R.layout.item_recycler, viewGroup, false);16       ret = new ViewHolder(v);17       return ret;18     }19 20 @Override21     public void onBindViewHolder(ViewHolder viewHolder, int i) {22       // 1.这里进行图片的加载23       viewHolder.textView.setText(strings.get(i));24       int resId = R.mipmap.ic_launcher;25       int index = i%5;26       switch (index){27         case 0:28           resId = R.mipmap.a11;29           break;30         case 1:31           resId = R.mipmap.a33;32           break;33         case 2:34           resId = R.mipmap.a22;35           break;36       }37       viewHolder.imageView.setImageResource(resId);38     }

View Code

 

---------------------------------------------------------------------------------------------------------------

完成自定义适配器和自定义ViewHolder的代码 就要进行RecyclerView的使用了

首先 要了解  RecyclerView.LayoutManager 这个属性

用于进行一个布局的设置,可以设置显示模式,ListView或者GridView或者瀑布流

1.ListView显示模式

1 // 1.线性布局2     LinearLayoutManager layoutManager =3         new LinearLayoutManager(this,  // 上下文4                     LinearLayout.VERTICAL, //垂直布局,5                     false);

                                    

2.GridView显示模式

1 // 2.Grid布局2     RecyclerView.LayoutManager layoutManager =3         new GridLayoutManager(this,4                    2, // 每行显示item项数目5                    GridLayoutManager.HORIZONTAL, //水平排列6                    false7                    );

                                    

3.瀑布流显示模式

1 // 3.瀑布流2     RecyclerView.LayoutManager layoutManager =3         new StaggeredGridLayoutManager(3, // 每行显示的item项数目4             StaggeredGridLayoutManager.VERTICAL); // 垂直排列

 

以上三种显示模式任意设置一种 就可以继续下面的代码

recyclerView.setLayoutManager(layoutManager);    // 设置 RecyclerView的Adapter    // 注意一定在设置了布局管理器之后调用    adapter = new MyRecycleAdapter(data);    recyclerView.setAdapter(adapter);

 

最后记得加上“添加一个数据”,“删除第一个数据”的按钮响应事件

public void btnAddItem(View view) {    data.add(0,"Time:"+System.currentTimeMillis());    adapter.notifyDataSetChanged();  }

  public void btnRemoveItem(View view) {    if (!data.isEmpty()) {      data.remove(0);    }    adapter.notifyItemRemoved(0);  }

 

完整代码:

 1 package com.xqx.superapp.app; 2  3 import android.app.Activity; 4 import android.content.Context; 5 import android.support.v7.app.ActionBarActivity; 6 import android.os.Bundle; 7 import android.support.v7.widget.GridLayoutManager; 8 import android.support.v7.widget.LinearLayoutManager; 9 import android.support.v7.widget.RecyclerView; 10 import android.support.v7.widget.StaggeredGridLayoutManager; 11 import android.util.Log; 12 import android.view.*; 13 import android.widget.*; 14  15 import java.util.LinkedList; 16 import java.util.List; 17  18  19 public class Android5Activity extends Activity { 20  21   private List<String> data; 22   private RecyclerView recyclerView; 23   private MyRecycleAdapter adapter; 24  25   @Override 26   protected void onCreate(Bundle savedInstanceState) { 27     super.onCreate(savedInstanceState); 28     setContentView(R.layout.activity_android5); 29     data = new LinkedList<String>(); 30     recyclerView = (RecyclerView) findViewById(R.id.recycle_view); 31     // 设置布局管理器 32     // 支持 单列线性排列,支持GridView模式,瀑布流模式 33     // 1.线性布局 34     LinearLayoutManager layoutManager = 35         new LinearLayoutManager(this,  // 上下文 36                     LinearLayout.VERTICAL, //垂直布局, 37                     false); 38  39 //    // 2.Grid布局 40 //    RecyclerView.LayoutManager layoutManager = 41 //        new GridLayoutManager(this, 42 //                   2, 43 //                   GridLayoutManager.HORIZONTAL, 44 //                   false 45 //                   ); 46 // 47 //     // 3.瀑布流 48 //    RecyclerView.LayoutManager layoutManager = 49 //        new StaggeredGridLayoutManager(3, 50 //            StaggeredGridLayoutManager.VERTICAL); 51     recyclerView.setLayoutManager(layoutManager); 52     // 设置 RecyclerView的Adapter 53     // 注意一定在设置了布局管理器之后调用 54     adapter = new MyRecycleAdapter(data); 55     recyclerView.setAdapter(adapter); 56   } 57  58   public void btnAddItem(View view) { 59     data.add(0,"Time:"+System.currentTimeMillis()); 60     adapter.notifyDataSetChanged(); 61   } 62  63   public void btnRemoveItem(View view) { 64     if (!data.isEmpty()) { 65       data.remove(0); 66     } 67     adapter.notifyItemRemoved(0); 68   } 69  70   /** 71    * 继承RecyclerView.Adapter,用于显示数据 72    * 需要定义并且使用 ViewHolder ,必须要使用 73   */ 74   private class MyRecycleAdapter extends RecyclerView.Adapter<ViewHolder>{ 75     private List<String> strings; 76     public MyRecycleAdapter(List<String> strings) { 77       this.strings = strings; 78     } 79  80     @Override 81     public int getItemCount() { 82       int ret = 0; 83       if (strings != null) { 84         ret = strings.size(); 85       } 86       return ret; 87     } 88  89     @Override 90     public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { 91       ViewHolder ret = null; 92       // 不需要检查是否复用,因为只要进入此方法,必然没有复用 93       // 因为RecyclerView 通过Holder检查复用 94       View v = LayoutInflater.from(Android5Activity.this).inflate(R.layout.item_recycler, viewGroup, false); 95       ret = new ViewHolder(v); 96       return ret; 97     } 98  99     @Override100     public void onBindViewHolder(ViewHolder viewHolder, int i) {101       viewHolder.textView.setText(strings.get(i));102       int resId = R.mipmap.ic_launcher;103       int index = i%5;104       switch (index){105         case 0:106           resId = R.mipmap.a11;107           break;108         case 1:109           resId = R.mipmap.a33;110           break;111         case 2:112           resId = R.mipmap.a22;113           break;114       }115       viewHolder.imageView.setImageResource(resId);116     }117   }118 119   /**120    * 创建自己的ViewHolder ,必须要继承RecyclerView.ViewHolder121   */122   private static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {123     public ImageView imageView;124     public TextView textView;125 126     public ViewHolder(View itemView) {127       super(itemView);128       // 通常ViewHolder的构造,就是用于获取控件视图的129       imageView = (ImageView) itemView.findViewById(R.id.item_icon);130       textView = (TextView) itemView.findViewById(R.id.item_title);131       // TODO 后续处理点击事件的操作132       itemView.setOnClickListener(this);133 134     }135     @Override136     public void onClick(View v) {137       int position = getAdapterPosition();138       Context context = imageView.getContext();139       Toast.makeText(context,"显示第"+position+"个项",Toast.LENGTH_SHORT).show();140     }141   }142 }

View Code