Android RecyclerView 的基本使用

我们做Android开发,当需要大量加载图片时,一般会用到ListView、GridView等,那么RecyclerView这样的控件又能做什么用呢,为什么要用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的整体使用思路如下:

  • 你想要控制其显示的方式,请通过布局管理器LayoutManager

  • 你想要控制Item间的间隔(可绘制),请通过ItemDecoration

  • 你想要控制Item增删的动画,请通过ItemAnimator
    通过以上三步设置,可以让RecyclerView显示出各种神奇的效果出来。

    RecyclerView使用过程如下:
1.RecyclerView是support-v7包中的新组件,使用之前需要导入support-v7。
![](http://upload-images.jianshu.io/upload_images/3897939-29f8b6abf7ba2310?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
2.activity_main.xml的布局如下,在布局文件里引用RecyclerView控件
<span style="font-family:SimHei;font-size:14px;"><?xml version="1.0" encoding="utf-8"?>  
<RelativeLayout 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.example.ahuang.recyclerview.MainActivity">  
  
    <android.support.v7.widget.RecyclerView  
        android:id="@+id/recyclerView"  
        android:layout_width="match_parent"  
        android:layout_height="match_parent">  
    </android.support.v7.widget.RecyclerView>  
</RelativeLayout>  
</span>  ```
###### 3.每个Item的布局如下,很简单,只有一个TextView

<span style="font-family:SimHei;font-size:14px;"><?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="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
</LinearLayout>
</span> ```

4. RecyclerView的适配器
  • RecyclerView的适配器继承自RecyclerView.Adapter
  • 重写内部类RecyclerView.ViewHolder
  • 实现onCreateViewHolder(),onBindViewHolder()和getItemCount()三个方法。
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>{  
   Context context;  
   List<String> list;  
 
   public MyAdapter(Context context,List<String> list){  
       this.context=context;  
       this.list=list;  
   }  
   @Override  
   public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
       MyViewHolder holder=new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.lv_item_layout,parent,false));  
 
       return holder;  
   }  
 
   @Override  
   public void onBindViewHolder(MyAdapter.MyViewHolder holder, int position) {  
       holder.tv.setText(list.get(position));  
   }  
 
   @Override  
   public int getItemCount() {  
       return list.size();  
   }  
 
   public class MyViewHolder extends RecyclerView.ViewHolder{  
 
       TextView tv;  
 
       public MyViewHolder(View itemView) {  
           super(itemView);  
           tv=(TextView) itemView.findViewById(R.id.textView);  
       }  
   }  
}  
</span>   ```
###### 5.主Activity中实现
只需上文提到的关键三步即可实现。

public class MainActivity extends ActionBarActivity {

private RecyclerView mRecyclerView;  
private List<String> list;  
private MyAdapter myAdapter;  

@Override  
protected void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState);  
    setContentView(R.layout.activity_main);  

    init();  
    mRecyclerView=(RecyclerView) findViewById(R.id.recyclerView);  
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this));  
    mRecyclerView.setAdapter(new MyAdapter(this,list));  

}  

private void init(){  
    list=new ArrayList<String>();  
    for(int i='A';i<'z';i++){  
        list.add(""+(char)i);  
    }  
}  

} ```
效果如下



但是,可以看到RecyclerView是没有分隔线的,而且RecyclerView并没有支持divider这样的属性,那应该怎样添加分割线呢,下面就用到了ItemDecoration,我们可以通过该方法添加分割线mRecyclerView.addItemDecoration(),通过它,我们可以随意地添加我们自定义的分割线。

当我们调用mRecyclerView.addItemDecoration()方法添加decoration的时候,RecyclerView在绘制的时候,去会绘制decorator,即调用该类的onDraw和onDrawOver方法,该类参考自:[DividerItemDecoration(http://blog.csdn.net/lmj623565791/article/details/38173061),代码如下

  • onDraw方法先于drawChildren
  • onDrawOver在drawChildren之后,一般我们选择复写其中一个即可。
  • getItemOffsets 可以通过outRect.set()为每个Item设置一定的偏移量,主要用于绘制Decorator。
/** 
 * Created by ahuang on 2016/1/8. 
 */  
public  class DividerItemDecoration extends RecyclerView.ItemDecoration{  
    private static final int[] ATTRS = new int[]{  
            android.R.attr.listDivider  
    };  
  
    public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;  
  
    public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;  
  
    private Drawable mDivider;  
  
    private int mOrientation;  
  
    public DividerItemDecoration(Context context, int orientation) {  
        final TypedArray a = context.obtainStyledAttributes(ATTRS);  
        mDivider = a.getDrawable(0);  
        a.recycle();  
        setOrientation(orientation);  
    }  
  
    public void setOrientation(int orientation) {  
        if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {  
            throw new IllegalArgumentException("invalid orientation");  
        }  
        mOrientation = orientation;  
    }  
  
    @Override  
    public void onDraw(Canvas c, RecyclerView parent) {  
        super.onDraw(c, parent);  
        if (mOrientation == VERTICAL_LIST) {  
            drawVertical(c, parent);  
        } else {  
            drawHorizontal(c, parent);  
        }  
    }  
    public void drawVertical(Canvas c, RecyclerView parent) {  
        final int left = parent.getPaddingLeft();  
        final int right = parent.getWidth() - parent.getPaddingRight();  
  
        final int childCount = parent.getChildCount();  
        for (int i = 0; i < childCount; i++) {  
            final View child = parent.getChildAt(i);  
            android.support.v7.widget.RecyclerView v = new android.support.v7.widget.RecyclerView(parent.getContext());  
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child  
                    .getLayoutParams();  
            final int top = child.getBottom() + params.bottomMargin;  
            final int bottom = top + mDivider.getIntrinsicHeight();  
            mDivider.setBounds(left, top, right, bottom);  
            mDivider.draw(c);  
        }  
    }  
  
    public void drawHorizontal(Canvas c, RecyclerView parent) {  
        final int top = parent.getPaddingTop();  
        final int bottom = parent.getHeight() - parent.getPaddingBottom();  
  
        final int childCount = parent.getChildCount();  
        for (int i = 0; i < childCount; i++) {  
            final View child = parent.getChildAt(i);  
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child  
                    .getLayoutParams();  
            final int left = child.getRight() + params.rightMargin;  
            final int right = left + mDivider.getIntrinsicHeight();  
            mDivider.setBounds(left, top, right, bottom);  
            mDivider.draw(c);  
        }  
    }  
  
    @Override  
    public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {  
        super.getItemOffsets(outRect, itemPosition, parent);  
        if (mOrientation == VERTICAL_LIST) {  
            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());  
        } else {  
            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);  
        }  
    }  
}  ```
前面说了,我们可以随意添加我们自定义的分割线,具体步骤如下:首先要自定义分割线,在drawable下画一个分割线的shape.
![](http://upload-images.jianshu.io/upload_images/3897939-7fc0c56b26b7fe67?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
在这个shape里,你可以自定义分割线的形状。

<pre name="code" class="java"><?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FFC125"></solid>
<size android:height="2dp"></size>
</shape> ```
接下来就是要将自定义的shape应用到RecyclerView中。

<pre name="code" class="java"><resources>  
    <!-- Base application theme. -->  
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">  
        <!-- Customize your theme here. -->  
        <item name="android:listDivider">@drawable/divider_bg</item>  
    </style>  
  
</resources>  ```
![](http://upload-images.jianshu.io/upload_images/3897939-a0f3a45271fed70c?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)效果图如此下:
            ![](http://upload-images.jianshu.io/upload_images/3897939-24cc71f47f7cbc9b?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 174,887评论 25 709
  • 写RecyclerView的博客很多 建议:博客专家写 RecyclerView:主要是在有限空间,展现大量数据,...
    沈凤德阅读 955评论 0 4
  • 生活本来就不容易,而我们的不努力只会让生活变得更加无赖 前几天依据《Android群英传》的学习写了一篇笔记是关于...
    AmatorLee阅读 3,787评论 7 23
  • Tangram是阿里出品、用于快速实现组合布局的框架模型,在手机天猫Android&iOS版 内广泛使用 该框架提...
    wintersweett阅读 3,445评论 0 1
  • 原文 不尚賢,使民不爭。不貴難得之貨,使民不為盜。不見可欲,使民不亂。 是以聖人之治也,虛其心,實其腹,弱其志,強...
    老貓說話阅读 212评论 0 0