zoukankan      html  css  js  c++  java
  • 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.   
    16.     // 创建Adapter,并指定数据集  
    17.     MyAdapter adapter = new MyAdapter(context, listData);  
    18.     // 设置Adapter  
    19.     recyclerView.setAdapter(adapter);  
          MyAdapter:
    [java] view plain copy
     
    1. public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MViewHolder> {  
    2.   
    3.     private Context context;  
    4.     private List<User> listData;  
    5.   
    6.     public MyAdapter(Context context, List<User> mList) {  
    7.         super();  
    8.         this.context = context;  
    9.         this.listData = mList;  
    10.     }  
    11.   
    12.     @Override  
    13.     public int getItemCount() {  
    14.         // TODO Auto-generated method stub  
    15.         return listData.size();  
    16.     }  
    17.   
    18.     @Override  
    19.     public MViewHolder onCreateViewHolder(ViewGroup viewGroup, int arg1) {  
    20.   
    21.         View view = View.inflate(viewGroup.getContext(),  
    22.                 R.layout.item_user_friend_nod, null);  
    23.         // 创建一个ViewHolder  
    24.         MViewHolder holder = new MViewHolder(view);  
    25.         return holder;  
    26.     }  
    27.   
    28.     @Override  
    29.     public void onBindViewHolder(MViewHolder mViewHolder, int arg1) {  
    30.   
    31.         mViewHolder.mTextView.setText(listData.get(arg1).getUsername());  
    32.         mViewHolder.image.setBackgroundResource(R.drawable.head);  
    33.   
    34.     }  
    35.   
    36.     public class MViewHolder extends RecyclerView.ViewHolder {  
    37.         public TextView mTextView;  
    38.         public ImageView image;  
    39.   
    40.         public MViewHolder(View view) {  
    41.             super(view);  
    42.             this.mTextView = (TextView) view.findViewById(R.id.tv_friend_name);  
    43.             this.image = (ImageView) itemView.findViewById(R.id.img_friend_avatar);  
    44.                       
    45.         }  
    46.     }  
    47.   
    48. }  
          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.     /** 
    10.      * Item 普通点击 
    11.      */  
    12.   
    13.     public void onItemClick(View view, int postion);  
    14.   
    15.     /** 
    16.      * Item 长按 
    17.      */  
    18.   
    19.     public void onItemLongClick(View view, int postion);  
    20.   
    21.     /** 
    22.      * Item 内部View点击 
    23.      */  
    24.   
    25.     public void onItemSubViewClick(View view, int postion);  
    26. }  
          然后再稍稍改造一下MyAdapter:
    [java] view plain copy
     
    1. public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MViewHolder> {  
    2.   
    3.     private Context context;  
    4.     private List<User> listData;  
    5.     private ItemClickListener mItemClickListener;  
    6.   
    7.     public MyAdapter(Context context, List<User> mList) {  
    8.         super();  
    9.         this.context = context;  
    10.         this.listData = mList;  
    11.     }  
    12.   
    13.     public void setItemClickListener(ItemClickListener mItemClickListener) {  
    14.   
    15.         this.mItemClickListener = mItemClickListener;  
    16.     }  
    17.   
    18.     @Override  
    19.     public int getItemCount() {  
    20.         // TODO Auto-generated method stub  
    21.         return listData.size();  
    22.     }  
    23.   
    24.     @Override  
    25.     public MViewHolder onCreateViewHolder(ViewGroup viewGroup, int arg1) {  
    26.   
    27.         View view = View.inflate(viewGroup.getContext(),  
    28.                 R.layout.item_user_friend_nod, null);  
    29.         // 创建一个ViewHolder  
    30.         MViewHolder holder = new MViewHolder(view);  
    31.         return holder;  
    32.     }  
    33.   
    34.     @Override  
    35.     public void onBindViewHolder(final MViewHolder mViewHolder,  
    36.             final int postion) {  
    37.   
    38.         mViewHolder.mTextView.setText(listData.get(postion).getUsername());  
    39.         mViewHolder.image.setBackgroundResource(R.drawable.head);  
    40.         // 为image添加监听回调  
    41.         mViewHolder.image.setOnClickListener(new OnClickListener() {  
    42.   
    43.             @Override  
    44.             public void onClick(View v) {  
    45.                 if (null != mItemClickListener) {  
    46.                     mItemClickListener.onItemSubViewClick(mViewHolder.image,  
    47.                             postion);  
    48.                 }  
    49.   
    50.             }  
    51.   
    52.         });  
    53.   
    54.     }  
    55.   
    56.     public class MViewHolder extends RecyclerView.ViewHolder {  
    57.         public TextView mTextView;  
    58.         public ImageView image;  
    59.   
    60.         public MViewHolder(final View view) {  
    61.             super(view);  
    62.             this.mTextView = (TextView) view.findViewById(R.id.tv_friend_name);  
    63.             this.image = (ImageView) itemView.findViewById(R.id.img_friend_avatar);  
    64.             //为item添加普通点击回调       
    65.             view.setOnClickListener(new OnClickListener() {  
    66.   
    67.                 @Override  
    68.                 public void onClick(View v) {  
    69.   
    70.                     if (null != mItemClickListener) {  
    71.                         mItemClickListener.onItemClick(view, getPosition());  
    72.                     }  
    73.   
    74.                 }  
    75.             });  
    76.   
    77.             //为item添加长按回调     
    78.             view.setOnLongClickListener(new OnLongClickListener() {  
    79.   
    80.                 @Override  
    81.                 public boolean onLongClick(View v) {  
    82.                     if (null != mItemClickListener) {  
    83.                         mItemClickListener.onItemLongClick(view, getPosition());  
    84.                     }  
    85.                     return true;  
    86.                 }  
    87.             });  
    88.   
    89.         }  
    90.     }  
    91.   
    92. }  
          对比以上的代码,只是在onBindViewHolder中为Item的子View添加监听回调,在MViewHolder的构造方法中为Item添加点击和长按监听回调。
          最后,在MainActivity中具体实例化我们的监听事件就OK啦!
    [java] view plain copy
     
    1. //为Item具体实例点击3种事件  
    2.         adapter.setItemClickListener(new ItemClickListener() {  
    3.               
    4.             @Override  
    5.             public void onItemSubViewClick(View view, int postion) {  
    6.                 T.showShort(context, "亲,你点击了Image"+postion);  
    7.                   
    8.             }  
    9.               
    10.             @Override  
    11.             public void onItemLongClick(View view, int postion) {  
    12.                 T.showShort(context, "亲,你长按了Item"+postion);  
    13.                   
    14.             }  
    15.               
    16.             @Override  
    17.             public void onItemClick(View view, int postion) {  
    18.                 T.showShort(context, "亲,你点击了Item"+postion);  
    19.                   
    20.             }  
    21.         });  

    为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.   
    5.     <RelativeLayout  
    6.         android:layout_width="match_parent"  
    7.         android:layout_height="wrap_content"  
    8.         android:background="@drawable/selector_item_action" >  
    9.   
    10.         <TextView  
    11.             android:id="@+id/tv_friend_name"  
    12.             android:layout_width="wrap_content"  
    13.             android:layout_height="wrap_content"  
    14.             android:layout_centerVertical="true"  
    15.             android:layout_marginLeft="20dp"  
    16.             android:layout_toRightOf="@+id/img_friend_avatar"  
    17.             android:text="test"  
    18.             android:textSize="18sp" />  
    19.   
    20.         <ImageView  
    21.             android:id="@+id/img_friend_avatar"  
    22.             android:layout_width="50dp"  
    23.             android:layout_height="50dp"  
    24.             android:layout_alignParentLeft="true"  
    25.             android:layout_marginBottom="8dip"  
    26.             android:layout_marginLeft="8dip"  
    27.             android:layout_marginTop="8dip"  
    28.             android:background="@drawable/ic_launcher" />  
    29.     </RelativeLayout>  
    30.   
    31.     <!-- 可以添加以下代码为Item之间设置分隔线  -->  
    32.    <View  
    33.         android:layout_width="match_parent"  
    34.         android:layout_height="1dp"  
    35.         android:layout_alignParentBottom="true"  
    36.         android:background="@drawable/divider_horizontal_line" />    
    37.      
    38.   
    39. </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.   
    3.     private Drawable mDivider;  
    4.     private int mOritation;  
    5.   
    6.     public ItemDecorationDivider(Context context, int resId, int oritation) {  
    7.   
    8.         mDivider = context.getResources().getDrawable(resId);  
    9.         this.mOritation = oritation;  
    10.         Log.i("ItemDecorationDivider", "mOritation=" + mOritation);  
    11.   
    12.     }  
    13.   
    14.     @Override  
    15.     public void onDrawOver(Canvas c, RecyclerView parent) {  
    16.   
    17.         if (mOritation == LinearLayoutManager.VERTICAL) {  
    18.             final int left = parent.getPaddingLeft();  
    19.             final int right = parent.getWidth() - parent.getPaddingRight();  
    20.   
    21.             final int childCount = parent.getChildCount();  
    22.             for (int i = 0; i childCount; i++) {  
    23.                 final View child = parent.getChildAt(i);  
    24.                 final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child  
    25.                         .getLayoutParams();  
    26.   
    27.                 final int top = child.getBottom() + params.bottomMargin;  
    28.                 final int bottom = top + mDivider.getIntrinsicHeight();  
    29.                 mDivider.setBounds(left, top, right, bottom);  
    30.                 mDivider.draw(c);  
    31.             }  
    32.         } else if (mOritation == LinearLayoutManager.HORIZONTAL) {  
    33.   
    34.             final int top = parent.getPaddingTop();  
    35.             // final int bottom = parent.getHeight() -  
    36.             // parent.getPaddingBottom();  
    37.   
    38.             final int childCount = parent.getChildCount();  
    39.             for (int i = 0; i childCount; i++) {  
    40.                 final View child = parent.getChildAt(i);  
    41.                 final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child  
    42.                         .getLayoutParams();  
    43.                 final int left = child.getRight() + params.rightMargin;  
    44.                 final int right = left + mDivider.getIntrinsicHeight();  
    45.   
    46.                 final int bottom = child.getBottom();  
    47.                 mDivider.setBounds(left, top, right, bottom);  
    48.                 mDivider.draw(c);  
    49.             }  
    50.         }  
    51.   
    52.     }  
    53.   
    54.     @Override  
    55.     public void getItemOffsets(Rect outRect, int position,  
    56.             RecyclerView parent) {  
    57.         if (mOritation == LinearLayoutManager.VERTICAL) {  
    58.             outRect.set(0, 0, 0, mDivider.getIntrinsicWidth());  
    59.             // outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());  
    60.         } else if (mOritation == LinearLayoutManager.HORIZONTAL) {  
    61.             // outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);  
    62.             outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());  
    63.         }  
    64.   
    65.     }  
    66. }  
    
    
    
    
     
          最主要的方法在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提供的的几个常用方法:
          主要是使用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.   
    5.     public void addData(User info, int position) {  
    6.         listData.add(position, info);  
    7.         notifyItemInserted(position);  
    8.     //  notifyDataSetChanged(); //不会触发Item的动画效果,告知数据改变,刷新UI  
    9.           
    10.     }  
    11.   
    12.     /** 
    13.      * TODO<添加数据到最后面添加> 
    14.      */  
    15.   
    16.     public void addData(User info) {  
    17.         // listData.add(position, info);  
    18.         // notifyItemInserted(position);  
    19.         listData.add(info);  
    20.         notifyDataSetChanged();  
    21.     }  
    22.   
    23.     /** 
    24.      * TODO<删除数据,指定其位置> 
    25.      */  
    26.     public void daleteData(int position) {  
    27.         listData.remove(position);  
    28.         notifyItemRemoved(position);  
    29.           
    30.     }  
    31.   
    32.     /** 
    33.      * TODO<某一位置开始,有itemCount个Item的数据删除> 
    34.      */  
    35.     public void itemRangeRemoved(int positionStart, int itemCount) {  
    36.         for (int i = positionStart; i < itemCount; i++) {  
    37.             listData.remove(positionStart);  
    38.         }  
    39.         notifyItemRangeRemoved(positionStart, itemCount);  
    40.     //  notifyDataSetChanged(); //不会触发Item的动画效果,告知数据改变,刷新UI  
    41.     }  
    42.   
    43.     /** 
    44.      * TODO<某一位置开始,有itemCount个Item的数据插入> 
    45.      */  
    46.     public void itemRangeInserted(User info, int positionStart, int itemCount) {  
    47.         for (int i = positionStart; i < itemCount; i++) {  
    48.             listData.add(i, info);  
    49.         }  
    50.         notifyItemRangeInserted(positionStart, itemCount);  
    51.         // notifyDataSetChanged();  
    52.     }  
    [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.   
    8.             @Override  
    9.             public void onScrolled(RecyclerView recyclerView, int i, int i2) {  
    10.   
    11.                 String s = "可见Item数量:" + layoutManager.getChildCount()+" "  
    12.                         + "可见Item第一个Position:"  
    13.                         + layoutManager.findFirstVisibleItemPosition()+" "  
    14.                         + "可见Item最后一个Position:"  
    15.                         + layoutManager.findLastVisibleItemPosition();  
    16.                 tv.setText(s);  
    17.             }  
    18.         });  

    [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.   
    8.         case SCROLL_STATE_DRAGGING:  
    9.             stateName = "Dragging";  
    10.             break;  
    11.   
    12.         case SCROLL_STATE_SETTLING:  
    13.             stateName = "Flinging";  
    14.             break;  
    15.         }  
    16.   
    17.         tv_state.setText("滑动状态:" + stateName);  
    18.     }  
          当滚动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更深入的用法在后面的博文中介绍。
     
  • 相关阅读:
    [计算机视觉]算法
    [python]python中**是什么
    ubuntu16.04增大swap空间
    conda查看某个安装包的依赖项
    conda install -c anaconda
    conda安装指定版本的指定包
    ValueError: Unable to determine SOCKS version from socks://127.0.0.1:1080/
    [ubuntu]卸载老版并安装最新版firefox
    使用anaconda创建tensorflow环境后如何在jupyter notebook中使用
    [python]numpy.mean()用法
  • 原文地址:https://www.cnblogs.com/hanfeihanfei/p/5545402.html
Copyright © 2011-2022 走看看