天天看點

Android RecyclerView的基本使用

Android RecyclerView 在去年的Google I/O大會上就推出來了,以前經常使用的ListView 繼承的是AbsListView,而RecyclerView則直接繼承 ViewGroup,并實作了ScrollingView 和 NestedScrollingChild接口,RecyclerView相比ListView,是一次徹底的改變,RecyclerView 比ListView更加強大靈活。

DEMO實作功能:

  • RecyclerView的點選事件: Item及item中的子View添加點選事件
  • RecyclerView Item之間添加分隔線:垂直與水準方向
  • RecyclerView 單個與多個Item的添加與删除
  • RecyclerView Item添加與删除動畫效果
  • RecyclerView滾動狀态監聽
  • LayoutManager的使用

DEMO效果圖:

RecyclerView的相關的LayoutManager ItemDecoration 和 ItemAnimator

  • LayoutManager:這個是為RecyclerView設定布局管理器的,決定RecyclerView的顯示風格,它有兩個直接子類:LinearLayoutManager 和 StaggeredGridLayoutManager,還有一個間接子類GridLayoutManager,GridLayoutManager繼承LinearLayoutManager 。線性布局管理器 LinearLayoutManager 的布局像ListView顯示多列,可以直接設定其布局方向(垂直或水準),網格布局管理器 GridLayoutManager像Gridview那樣顯示多行多列,而StaggeredGridLayoutManager則可以實作流式布局。
  • ItemDecoration:在Item之間設定分隔線和偏移,提供了三個方法:getItemOffsets,onDraw,onDrawOver。ItemDecoration的繪制是有一定的順序的,onDraw的繪制在Item視圖繪制之前,onDrawOver 的繪制在Item視圖繪制之後,并将其繪制的顯示在視圖之上,getItemOffsets為Item設定偏移量。如果你隻是想實作簡單的Item之間的分割線的話,可以直接在item的XML檔案中直接定義就可以了。
  • ItemAnimator:用來設定item的添加或者删除的動畫風格,預設的動畫是DefaultItemAnimator,也可以自己設定,繼承RecyclerView.ItemAnimator,然後重寫animateAdd,animateMove等方法就可以了。     

      來看看一個簡單的例子: 

      XML中添加RecyclerView:

[html] view plain copy

  1. <android.support.v7.widget.RecyclerView  
  2.        android:id="@+id/recyclerview"  
  3.        android:layout_width="match_parent"  
  4.        android:layout_height="0dp"  
  5.        android:layout_weight="1"  
  6.        android:scrollbars="vertical" />  

      如果想水準排列顯示,把layoutManager.setOrientation(LinearLayoutManager.VERTICAL)替換成layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL)即可。

[java] view plain copy

  1. // 如果布局大小一緻有利于優化  
  2.     recyclerView.setHasFixedSize(true);  
  3.     // 建立一個線性布局管理器  
  4.     LinearLayoutManager layoutManager = new LinearLayoutManager(this);  
  5.     layoutManager.setOrientation(LinearLayoutManager.VERTICAL);  
  6.     // 設定布局管理器  
  7.     recyclerView.setLayoutManager(layoutManager);  
  8.     // 建立資料集  
  9.     List<User> listData = new ArrayList<User>();  
  10.     for (int i = 0; i < 20; ++i) {  
  11.         User uBean = new User();  
  12.         uBean.setUsername("我是Item" + i);  
  13.         listData.add(uBean);  
  14.     }  
  15.     // 建立Adapter,并指定資料集  
  16.     MyAdapter adapter = new MyAdapter(context, listData);  
  17.     // 設定Adapter  
  18.     recyclerView.setAdapter(adapter);  

      MyAdapter:

[java] view plain copy

  1. public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MViewHolder> {  
  2.     private Context context;  
  3.     private List<User> listData;  
  4.     public MyAdapter(Context context, List<User> mList) {  
  5.         super();  
  6.         this.context = context;  
  7.         this.listData = mList;  
  8.     }  
  9.     @Override  
  10.     public int getItemCount() {  
  11.         // TODO Auto-generated method stub  
  12.         return listData.size();  
  13.     }  
  14.     @Override  
  15.     public MViewHolder onCreateViewHolder(ViewGroup viewGroup, int arg1) {  
  16.         View view = View.inflate(viewGroup.getContext(),  
  17.                 R.layout.item_user_friend_nod, null);  
  18.         // 建立一個ViewHolder  
  19.         MViewHolder holder = new MViewHolder(view);  
  20.         return holder;  
  21.     }  
  22.     @Override  
  23.     public void onBindViewHolder(MViewHolder mViewHolder, int arg1) {  
  24.         mViewHolder.mTextView.setText(listData.get(arg1).getUsername());  
  25.         mViewHolder.image.setBackgroundResource(R.drawable.head);  
  26.     }  
  27.     public class MViewHolder extends RecyclerView.ViewHolder {  
  28.         public TextView mTextView;  
  29.         public ImageView image;  
  30.         public MViewHolder(View view) {  
  31.             super(view);  
  32.             this.mTextView = (TextView) view.findViewById(R.id.tv_friend_name);  
  33.             this.image = (ImageView) itemView.findViewById(R.id.img_friend_avatar);  
  34.         }  
  35.     }  
  36. }  

      MViewHolder是一個内部類,在其構造函數中,擷取控件。 MyAdapter繼承了RecyclerView.Adapter<ViewHolder>,并重寫了getItemCount(),onCreateViewHolder和onBindViewHolder三個方法。

為RecyclerView的Item及item中的子View添加點選事件

      RecyclerView并沒有像ListView那樣提供OnItemClickListener和OnLongClickListener的回調,為了給RecyclerView添加Onclick監聽,需要自己去實作其Onclick監聽方法再對外公開。

      首先,定義一個接口,并在裡面聲明3個監聽回調函數,分别是Item普通點選監聽,Item長按監聽和Item内部View點選監聽。

[java] view plain copy

  1. /** 
  2.  * item點選回調接口 
  3.  *  
  4.  * @author wen_er 
  5.  *  
  6.  */  
  7. public interface ItemClickListener {  
  8.     /** 
  9.      * Item 普通點選 
  10.      */  
  11.     public void onItemClick(View view, int postion);  
  12.     /** 
  13.      * Item 長按 
  14.      */  
  15.     public void onItemLongClick(View view, int postion);  
  16.     /** 
  17.      * Item 内部View點選 
  18.      */  
  19.     public void onItemSubViewClick(View view, int postion);  
  20. }  

      然後再稍稍改造一下MyAdapter:

[java] view plain copy

  1. public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MViewHolder> {  
  2.     private Context context;  
  3.     private List<User> listData;  
  4.     private ItemClickListener mItemClickListener;  
  5.     public MyAdapter(Context context, List<User> mList) {  
  6.         super();  
  7.         this.context = context;  
  8.         this.listData = mList;  
  9.     }  
  10.     public void setItemClickListener(ItemClickListener mItemClickListener) {  
  11.         this.mItemClickListener = mItemClickListener;  
  12.     }  
  13.     @Override  
  14.     public int getItemCount() {  
  15.         // TODO Auto-generated method stub  
  16.         return listData.size();  
  17.     }  
  18.     @Override  
  19.     public MViewHolder onCreateViewHolder(ViewGroup viewGroup, int arg1) {  
  20.         View view = View.inflate(viewGroup.getContext(),  
  21.                 R.layout.item_user_friend_nod, null);  
  22.         // 建立一個ViewHolder  
  23.         MViewHolder holder = new MViewHolder(view);  
  24.         return holder;  
  25.     }  
  26.     @Override  
  27.     public void onBindViewHolder(final MViewHolder mViewHolder,  
  28.             final int postion) {  
  29.         mViewHolder.mTextView.setText(listData.get(postion).getUsername());  
  30.         mViewHolder.image.setBackgroundResource(R.drawable.head);  
  31.         // 為image添加監聽回調  
  32.         mViewHolder.image.setOnClickListener(new OnClickListener() {  
  33.             @Override  
  34.             public void onClick(View v) {  
  35.                 if (null != mItemClickListener) {  
  36.                     mItemClickListener.onItemSubViewClick(mViewHolder.image,  
  37.                             postion);  
  38.                 }  
  39.             }  
  40.         });  
  41.     }  
  42.     public class MViewHolder extends RecyclerView.ViewHolder {  
  43.         public TextView mTextView;  
  44.         public ImageView image;  
  45.         public MViewHolder(final View view) {  
  46.             super(view);  
  47.             this.mTextView = (TextView) view.findViewById(R.id.tv_friend_name);  
  48.             this.image = (ImageView) itemView.findViewById(R.id.img_friend_avatar);  
  49.             //為item添加普通點選回調       
  50.             view.setOnClickListener(new OnClickListener() {  
  51.                 @Override  
  52.                 public void onClick(View v) {  
  53.                     if (null != mItemClickListener) {  
  54.                         mItemClickListener.onItemClick(view, getPosition());  
  55.                     }  
  56.                 }  
  57.             });  
  58.             //為item添加長按回調     
  59.             view.setOnLongClickListener(new OnLongClickListener() {  
  60.                 @Override  
  61.                 public boolean onLongClick(View v) {  
  62.                     if (null != mItemClickListener) {  
  63.                         mItemClickListener.onItemLongClick(view, getPosition());  
  64.                     }  
  65.                     return true;  
  66.                 }  
  67.             });  
  68.         }  
  69.     }  
  70. }  

      對比以上的代碼,隻是在onBindViewHolder中為Item的子View添加監聽回調,在MViewHolder的構造方法中為Item添加點選和長按監聽回調。

      最後,在MainActivity中具體執行個體化我們的監聽事件就OK啦!

[java] view plain copy

  1. //為Item具體執行個體點選3種事件  
  2.         adapter.setItemClickListener(new ItemClickListener() {  
  3.             @Override  
  4.             public void onItemSubViewClick(View view, int postion) {  
  5.                 T.showShort(context, "親,你點選了Image"+postion);  
  6.             }  
  7.             @Override  
  8.             public void onItemLongClick(View view, int postion) {  
  9.                 T.showShort(context, "親,你長按了Item"+postion);  
  10.             }  
  11.             @Override  
  12.             public void onItemClick(View view, int postion) {  
  13.                 T.showShort(context, "親,你點選了Item"+postion);  
  14.             }  
  15.         });  

為Item之間添加分隔線

      如果想要給RecyclerView的Item之間添加分隔線,可以使用addItemDecoration,但如果想圖友善,就直接在Item對應的XML中定義就可以了,比如說,像這樣(下面的例子隻适合Item垂直布局)

[html] view plain copy

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:layout_width="match_parent"  
  3.     android:layout_height="match_parent" >  
  4.     <RelativeLayout  
  5.         android:layout_width="match_parent"  
  6.         android:layout_height="wrap_content"  
  7.         android:background="@drawable/selector_item_action" >  
  8.         <TextView  
  9.             android:id="@+id/tv_friend_name"  
  10.             android:layout_width="wrap_content"  
  11.             android:layout_height="wrap_content"  
  12.             android:layout_centerVertical="true"  
  13.             android:layout_marginLeft="20dp"  
  14.             android:layout_toRightOf="@+id/img_friend_avatar"  
  15.             android:text="test"  
  16.             android:textSize="18sp" />  
  17.         <ImageView  
  18.             android:id="@+id/img_friend_avatar"  
  19.             android:layout_width="50dp"  
  20.             android:layout_height="50dp"  
  21.             android:layout_alignParentLeft="true"  
  22.             android:layout_marginBottom="8dip"  
  23.             android:layout_marginLeft="8dip"  
  24.             android:layout_marginTop="8dip"  
  25.             android:background="@drawable/ic_launcher" />  
  26.     </RelativeLayout>  
  27.     <!-- 可以添加以下代碼為Item之間設定分隔線  -->  
  28.    <View  
  29.         android:layout_width="match_parent"  
  30.         android:layout_height="1dp"  
  31.         android:layout_alignParentBottom="true"  
  32.         android:background="@drawable/divider_horizontal_line" />    
  33. </RelativeLayout>  

      addItemDecoration的參數ItemDecoration需要我們重寫它的onDraw,onDrawOver和getItemOffsets方法,因為item可能是水準排列,也可能是垂直排列,是以我們傳入一個參數oritation值,作為item排列方向的标記,參考了Git上的代碼,原來的代碼當水準布局時,分隔線的高度會填滿整個螢幕(Item并未填滿整個螢幕),是以稍稍做了改動。

[html] view plain copy

  1. <pre name="code" class="java">public class ItemDecorationDivider extends ItemDecoration {  
  2.     private Drawable mDivider;  
  3.     private int mOritation;  
  4.     public ItemDecorationDivider(Context context, int resId, int oritation) {  
  5.         mDivider = context.getResources().getDrawable(resId);  
  6.         this.mOritation = oritation;  
  7.         Log.i("ItemDecorationDivider", "mOritation=" + mOritation);  
  8.     }  
  9.     @Override  
  10.     public void onDrawOver(Canvas c, RecyclerView parent) {  
  11.         if (mOritation == LinearLayoutManager.VERTICAL) {  
  12.             final int left = parent.getPaddingLeft();  
  13.             final int right = parent.getWidth() - parent.getPaddingRight();  
  14.             final int childCount = parent.getChildCount();  
  15.             for (int i = 0; i < childCount; i++) {  
  16.                 final View child = parent.getChildAt(i);  
  17.                 final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child  
  18.                         .getLayoutParams();  
  19.                 final int top = child.getBottom() + params.bottomMargin;  
  20.                 final int bottom = top + mDivider.getIntrinsicHeight();  
  21.                 mDivider.setBounds(left, top, right, bottom);  
  22.                 mDivider.draw(c);  
  23.             }  
  24.         } else if (mOritation == LinearLayoutManager.HORIZONTAL) {  
  25.             final int top = parent.getPaddingTop();  
  26.             // final int bottom = parent.getHeight() -  
  27.             // parent.getPaddingBottom();  
  28.             final int childCount = parent.getChildCount();  
  29.             for (int i = 0; i < childCount; i++) {  
  30.                 final View child = parent.getChildAt(i);  
  31.                 final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child  
  32.                         .getLayoutParams();  
  33.                 final int left = child.getRight() + params.rightMargin;  
  34.                 final int right = left + mDivider.getIntrinsicHeight();  
  35.                 final int bottom = child.getBottom();  
  36.                 mDivider.setBounds(left, top, right, bottom);  
  37.                 mDivider.draw(c);  
  38.             }  
  39.         }  
  40.     }  
  41.     @Override  
  42.     public void getItemOffsets(Rect outRect, int position,  
  43.             RecyclerView parent) {  
  44.         if (mOritation == LinearLayoutManager.VERTICAL) {  
  45.             outRect.set(0, 0, 0, mDivider.getIntrinsicWidth());  
  46.             // outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());  
  47.         } else if (mOritation == LinearLayoutManager.HORIZONTAL) {  
  48.             // outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);  
  49.             outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());  
  50.         }  
  51.     }  
  52. }  

      最主要的方法在onDrawOver中,

      mDrawable是Item之間分隔的Drawable資源,

      mDrawable.setBounds(left, top, right, bottom)設定分隔線的繪制範圍,再繪制出來 ,

      getItemOffsets為Item設定偏移量,告知RecyclerView需要繪制Item之間分隔線,然後把實作的ItemDivider作為參數傳給recyclerView.addItemDecoration。

[java] view plain copy

  1. recyclerView.addItemDecoration(new ItemDecorationDivider(context,  
  2.                 R.drawable.item_divider, LinearLayoutManager.VERTICAL));  

item_divider:

[html] view plain copy

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <shape xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:shape="rectangle" >  
  4.     <solid android:color="#CCCCCC" />  
  5.     <size android:height="1dp" />  
  6. </shape>  

RecyclerView Item的添加與删除

      Adapter提供的的幾個常用方法:

  •       notifyItemChanged(int position) 

    //通知位置position的Item的資料改變

    •       notifyItemInserted(int)//通知位置position的Item的資料插入

    •       notifyItemRemoved(int)//通知位置position的Item的資料移除

  •       notifyItemRangeChanged(int positionStart, int itemCount) //通知從位置positionStart開始,有itemCount個Item的資料發生改變

  •       notifyItemRangeInserted(int positionStart, int itemCount) //通知從位置positionStart開始,有itemCount個Item的資料插入

  •       notifyItemRangeRemoved(int positionStart, int itemCount)//通知從位置positionStart開始,有itemCount個Item的資料移除

      主要是使用Adapter提供的notifyItemInserted(position)和notifyItemRemoved(position)方法,告知資料改變,如果删除或者添加Item都是從Position為0的位置開始,加上notifyDataSetChanged()重新整理一下UI。

      注意:使用notifyDataSetChanged()不會觸發Item的動畫效果。

[java] view plain copy

  1. </pre><pre name="code" class="java">    /** 
  2.      * TODO<添加資料,指定其位置> 
  3.      */  
  4.     public void addData(User info, int position) {  
  5.         listData.add(position, info);  
  6.         notifyItemInserted(position);  
  7.     //  notifyDataSetChanged(); //不會觸發Item的動畫效果,告知資料改變,重新整理UI  
  8.     }  
  9.     /** 
  10.      * TODO<添加資料到最後面添加> 
  11.      */  
  12.     public void addData(User info) {  
  13.         // listData.add(position, info);  
  14.         // notifyItemInserted(position);  
  15.         listData.add(info);  
  16.         notifyDataSetChanged();  
  17.     }  
  18.     /** 
  19.      * TODO<删除資料,指定其位置> 
  20.      */  
  21.     public void daleteData(int position) {  
  22.         listData.remove(position);  
  23.         notifyItemRemoved(position);  
  24.     }  
  25.     /** 
  26.      * TODO<某一位置開始,有itemCount個Item的資料删除> 
  27.      */  
  28.     public void itemRangeRemoved(int positionStart, int itemCount) {  
  29.         for (int i = positionStart; i < itemCount; i++) {  
  30.             listData.remove(positionStart);  
  31.         }  
  32.         notifyItemRangeRemoved(positionStart, itemCount);  
  33.     //  notifyDataSetChanged(); //不會觸發Item的動畫效果,告知資料改變,重新整理UI  
  34.     }  
  35.     /** 
  36.      * TODO<某一位置開始,有itemCount個Item的資料插入> 
  37.      */  
  38.     public void itemRangeInserted(User info, int positionStart, int itemCount) {  
  39.         for (int i = positionStart; i < itemCount; i++) {  
  40.             listData.add(i, info);  
  41.         }  
  42.         notifyItemRangeInserted(positionStart, itemCount);  
  43.         // notifyDataSetChanged();  
  44.     }  

[java] view plain copy

  1. </pre><pre>  

      直接使用:

[java] view plain copy

  1. case R.id.btn3:  
  2.             User uBean = new User();  
  3.             uBean.setUsername("我是增加的Item");  
  4.             adapter.addData(uBean, 0);// 添加到第一個  
  5.             break;  
  6.         case R.id.btn4:  
  7.             adapter.daleteData(0); // 删除第一個  
  8.             break;  
  9.         case R.id.btn5:  
  10.             User uBean1 = new User();  
  11.             uBean1.setUsername("我是連續添加的Item");  
  12.             adapter.itemRangeInserted(uBean1, 0, 5);  
  13.             break;  
  14.         case R.id.btn6:  
  15.             adapter.itemRangeRemoved(0, 5);  
  16.             break;  

為RecyclerView的Item添加動畫

      在在ListView中,給item添加動畫的常用方式是,使用LayoutAnimationController為ViewGroup添加動畫,在RecyclerView中,則使用RecyclerView提供的setItemAnimator()方法

[java] view plain copy

  1. // 使用RecyclerView提供的預設的動畫效果  
  2.     recyclerView.setItemAnimator(new DefaultItemAnimator());  

      這就是我們在效果圖看到的動畫效果,如果想要其它的動畫效果,參見GitHub:https://github.com/gabrielemariotti/RecyclerViewItemAnimators

      目前提供了:ScaleInOutItemAnimator,SlideInOutBottomItemAnimator,SlideInOutLeftItemAnimator,SlideInOutRightItemAnimator,SlideInOutTopItemAnimator,SlideScaleInOutRightItemAnimator幾種動畫效果,使用方法相似。  

RecyclerView滾動狀态監聽

      RecyclerView提供了setOnScrollListener方法,以便監聽螢幕滾動狀态。

[java] view plain copy

  1. recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {  
  2.             @Override  
  3.             public void onScrollStateChanged(RecyclerView recyclerView,  
  4.                     int scrollState) {  
  5.                 updateState(scrollState);  
  6.             }  
  7.             @Override  
  8.             public void onScrolled(RecyclerView recyclerView, int i, int i2) {  
  9.                 String s = "可見Item數量:" + layoutManager.getChildCount()+"\n"  
  10.                         + "可見Item第一個Position:"  
  11.                         + layoutManager.findFirstVisibleItemPosition()+"\n"  
  12.                         + "可見Item最後一個Position:"  
  13.                         + layoutManager.findLastVisibleItemPosition();  
  14.                 tv.setText(s);  
  15.             }  
  16.         });  

[java] view plain copy

  1. private void updateState(int scrollState) {  
  2.         String stateName = "Undefined";  
  3.         switch (scrollState) {  
  4.         case SCROLL_STATE_IDLE:  
  5.             stateName = "Idle";  
  6.             break;  
  7.         case SCROLL_STATE_DRAGGING:  
  8.             stateName = "Dragging";  
  9.             break;  
  10.         case SCROLL_STATE_SETTLING:  
  11.             stateName = "Flinging";  
  12.             break;  
  13.         }  
  14.         tv_state.setText("滑動狀态:" + stateName);  
  15.     }  

      當滾動RecyclerView的時候,效果如DEMO效果圖所示。

最後看看LayoutManager,前面說過,LayoutManager是為RecyclerView設定布局管理器的,決定RecyclerView的顯示風格。

  • LinearLayoutManager

前面的代碼中,使用

LinearLayoutManager layoutManager = new LinearLayoutManager(this)和

layoutManager.setOrientation(LinearLayoutManager.VERTICAL)建立一個線性布局管理器和設定其布局方向

還可以使用直接以下使用構造方法傳入布局方向:

LinearLayoutManager(Context context, int orientation, boolean reverseLayout)

第二個參數為布局方向:LinearLayoutManager.HORIZONTAL或者LinearLayoutManager.VERTICAL

第三個參數:true或者false,決定布局是否反向

  • GridLayoutManager

      這是類似GridView的網格布局,三個構造函數:

      GridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) //可以直接在XMl中設定RecyclerView 屬性"layoutManager".

      GridLayoutManager(Context context, int spanCount) //spanCount為列數,預設方向vertical

      GridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout)//spanCount為列數,orientation為布局方向,reverseLayout決定布局是否反向。

[java] view plain copy

  1. gridLayoutManager = new GridLayoutManager(this, 3,  
  2.                 GridLayoutManager.VERTICAL, false);  
  3.         // 設定布局管理器  
  4.         recyclerView.setLayoutManager(gridLayoutManager);  
  • StaggeredGridLayoutManager

      流式布局,兩個構造函數:

      StaggeredGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)

      StaggeredGridLayoutManager(int spanCount, int orientation) //spanCount為列數,orientation為布局方向

[java] view plain copy

  1. StaggeredGridLayoutManager = new StaggeredGridLayoutManager(2,  
  2.                 StaggeredGridLayoutManager.VERTICAL);  
  3.         // 設定布局管理器  
  4.         recyclerView.setLayoutManager(StaggeredGridLayoutManager);  

      LinearLayoutManager,GridLayoutManager和StaggeredGridLayoutManager使用方法都類似,直接作為參數傳給setLayoutManager就可以了。

      關于RecyclerView更深入的用法在後面的博文中介紹。

GITHUb下載下傳位址:https://github.com/myjoybar/Android-RecyclerView

CSDN下載下傳位址:http://download.csdn.net/detail/yalinfendou/8837997

Android RecyclerView的基本使用