`

android RecyclerView使用及详解

 
阅读更多
1.前言

话说RecyclerView已经面市很久,也在很多应用中得到广泛的使用,在整个开发者圈子里面也拥有很不错的口碑,那说明RecyclerView拥有比ListView,GridView之类控件有很多的优点,例如:数据绑定,Item View创建,View的回收以及重用等机制。那么今天开始我们来重点学习一下RecyclerView控件,本系列文章会包括到以下三个部分:
RecyclerView控件的基本使用,包括基础,进阶,高级部分,动画之类
RecyclerView控件的实战实例
RecyclerView控件集合AA(Android Annotations)注入框架实例
那么今天我们首先来看第一部分:RecyclerView控件的基本使用,进阶,动画相关知识点。
本次讲解所有用的Demo例子已经全部更新到下面的项目中了,欢迎大家star和fork。
FastDev4Android框架项目地址:https://github.com/jiangqqlmj/FastDev4Android


2.RecyclerView基本介绍

通过使用RecyclerView控件,我们可以在APP中创建带有Material Design风格的复杂列表
RecyclerView控件和ListView的原理有很多相似的地方,都是维护少量的View来进行显示大量的数据,不过RecyclerView控件比ListView更加高级并且更加灵活。
当我们的数据因为用户事件或者网络事件发生改变的时候也能很好的进行显示。和ListView不同的是,RecyclerView不用在负责Item的显示相关的功能,在这边所有有关布局,绘制,数据绑定等都被分拆成不同的类进行管理,下面我这边会一个个的进行讲解。同时RecyclerView控件提供了以下两种方法来进行简化和处理大数量集合:

采用LayoutManager来处理Item的布局
提供Item操作的默认动画,例如在增加或者删除item的时候
你也可以自定义LayoutManager或者设置添加/删除的动画,整体的RecyclerView结构图如下:



为了使用RecyclerView控件,我们需要创建一个Adapter和一个LayoutManager

Adapter:继承自RecyclerView.Adapetr类,主要用来将数据和布局item进行绑定

LayoutManager:布局管理器,设置每一项view在RecyclerView中的位置布局以及控件item view的显示或者隐藏。
当View重用或者回收的时候,LayoutManger都会向Adapter来请求新的数据来进行替换原来数据的内容。这种回收重用的机制可以提供性能,避免创建很多的view或者是频繁的调用findViewById方法。这种机制和ListView还是很相似的。

RecyclerView提供了三种内置的LayoutManager

LinearLayoutManager:线性布局,横向或者纵向滑动列表
GridLayoutManager:表格布局
StaggeredGridLayoutManager:流式布局,例如瀑布流效果
当然除了上面的三种内部布局之外,我们还可以继承RecyclerView.LayoutManager来实现一个自定义的LayoutManager。

Animations(动画)效果:

RecyclerView对于Item的添加和删除是默认开启动画的。我们当然也可以通过RecyclerView.ItemAnimator类定制动画,然后通过RecyclerView.setItemAnimator()方法来进行使用。



3.RecyclerView基本实现

新建布局,引入RecyclerView控件

<?xmlversionxmlversion="1.0" encoding="utf-8"?>  
<LinearLayoutxmlns:androidLinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"  
    android:orientation="vertical"android:layout_width="match_parent"  
   android:layout_height="match_parent">  
    <includelayoutincludelayout="@layout/common_top_bar_layout"/>  
   
    <android.support.v7.widget.RecyclerView  
       android:id="@+id/recyclerView_one"  
       android:layout_width="match_parent"  
       android:layout_height="match_parent"  
        android:scrollbars="vertical"  
       ></android.support.v7.widget.RecyclerView>  
</LinearLayout>  


在Activity中获取RecyclerView控件然后进行设置LayoutManger以及Adapter即可,和ListView的写法有点类似:

public class RecyclerViewTestActivity extends BaseActivity {  
    private LinearLayout top_bar_linear_back;  
    private TextView top_bar_title;  
    private RecyclerView recyclerView_one;  
    private RecyclerView.Adapter mAdapter;  
    private LinearLayoutManager mLayoutManager;  
    @Override
    protected void onCreate(BundlesavedInstanceState) {  
       super.onCreate(savedInstanceState);  
       setContentView(R.layout.recyclerview_test_layout);  
       top_bar_linear_back=(LinearLayout)this.findViewById(R.id.top_bar_linear_back);  
       top_bar_linear_back.setOnClickListener(new CustomOnClickListener());  
       top_bar_title=(TextView)this.findViewById(R.id.top_bar_title);  
       top_bar_title.setText("RecyclerView使用实例");  
        //开始设置RecyclerView  
       recyclerView_one=(RecyclerView)this.findViewById(R.id.recyclerView_one);  
        //设置固定大小  
        recyclerView_one.setHasFixedSize(true);  
        //创建线性布局  
        mLayoutManager = new LinearLayoutManager(this);  
         //垂直方向  
       mLayoutManager.setOrientation(OrientationHelper.VERTICAL);  
        //给RecyclerView设置布局管理器  
       recyclerView_one.setLayoutManager(mLayoutManager);  
        //创建适配器,并且设置  
        mAdapter = newTestRecyclerAdapter(this);  
        recyclerView_one.setAdapter(mAdapter);  
    }  
    class CustomOnClickListener implements View.OnClickListener{  
        @Override  
        public void onClick(View v) {  
           RecyclerViewTestActivity.this.finish();  
        }  
    }  
} 


自定义一个适配器来进行创建item view以及绑定数据

public class TestRecyclerAdapter extends RecyclerView.Adapter<TestRecyclerAdapter.ViewHolder>{  
    private LayoutInflater mInflater;  
    private String[] mTitles=null;  
    public TestRecyclerAdapter(Context context){  
       this.mInflater=LayoutInflater.from(context);  
        this.mTitles=new String[20];  
        for (int i=0;i<20;i++){  
            int index=i+1;  
            mTitles[i]="item"+index;  
        }  
    }  
    /** 
     * item显示类型 
     * @param parent 
     * @param viewType 
     * @return 
     */  
    @Override  
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
        Viewview=mInflater.inflate(R.layout.item_recycler_layout,parent,false);  
        //view.setBackgroundColor(Color.RED);  
        ViewHolder viewHolder=new ViewHolder(view);  
        return viewHolder;  
    }  
    /** 
     * 数据的绑定显示 
     * @param holder 
     * @param position 
     */  
    @Override  
    public void onBindViewHolder(ViewHolder holder, int position) {  
       holder.item_tv.setText(mTitles[position]);  
    }  
   
    @Override  
    public int getItemCount() {  
        return mTitles.length;  
    }  
   
    //自定义的ViewHolder,持有每个Item的的所有界面元素  
    public static class ViewHolder extends RecyclerView.ViewHolder {  
        public TextView item_tv;  
        public ViewHolder(View view){  
            super(view);  
            item_tv = (TextView)view.findViewById(R.id.item_tv);  
        }  
    } 


这个自定义Adapter和我们在使用Listview时候的Adapter相比还是有点不太一样的,首先这边我们需要继承RecyclerView.Adaper类,然后实现两个重要的方法onBindViewHodler()以及onCreateViewHolder(),这边我们看出来区别,使用RecyclerView控件我们就可以把Item View视图创建和数据绑定这两步进行分来进行管理,用法就更加方便而且灵活了,并且我们可以定制打造千变万化的布局。同时这边我们还需要创建一个ViewHolder类,该类必须继承自RecyclerView.ViewHolder类,现在Google也要求我们必须要实现ViewHolder来承载Item的视图。

上面的例子我们这边比较简单使用LinearLayoutManager来实现了,其中布局是采用垂直布局的,当然我们还可以设置线性布局的方向为横向,只要如下设置即可:

mLayoutManager.setOrientation(OrientationHelper.HORIZONTAL); 


那么另外两种内置的布局如下

1.GridLayoutManger:使用如下设置:

GridLayoutManager girdLayoutManager=new GridLayoutManager(this,4);  
recyclerView_one.setLayoutManager(girdLayoutManager);


2.GridLayoutManger:使用如下设置:

StaggeredGridLayoutManager staggeredGridLayoutManager=new   StaggeredGridLayoutManager(2,OrientationHelper.VERTICAL);  
recyclerView_one.setLayoutManager(staggeredGridLayoutManager); 


4.RecyclerView分隔线实现(ItemDecoration)

大家肯定观察到上面的显示效果还是比较丑,例如就没有分隔线这个效果,下面我们一起来实现以下分隔线的效果。还记得前面的一个表格中有写关于RecyclerView的相关类:

RecyclerView.ItemDecoration

给每一项Item视图添加子View,可以进行画分隔线之类的东西

我们可以创建一个继承RecyclerView.ItemDecoration类来绘制分隔线,通过ItemDecoration可 以让我们每一个Item从视觉上面相互分开来,例如ListView的divider非常相似的效果。当然像我们上面的例子ItemDecoration 我们没有设置也没有报错哦,那说明ItemDecoration我们并不是强制需要使用,作为我们开发者可以设置或者不设置Decoration的。实现一个ItemDecoration,系统提供的ItemDecoration是一个抽象类,内部除去已经废弃的方法以外,我们主要实现以下三个方法:

public static abstract class ItemDecoration {  
       public void onDraw(Canvas c,RecyclerView parent, State state) {  
            onDraw(c, parent);  
        }  
        public void onDrawOver(Canvas c,RecyclerView parent, State state) {  
            onDrawOver(c, parent);  
        }  
        public void getItemOffsets(RectoutRect, View view, RecyclerView parent, State state) {  
            getItemOffsets(outRect,((LayoutParams) view.getLayoutParams()).getViewLayoutPosition(),  
                    parent);  
        }  
} 


因为当我们RecyclerView在进行绘制的时候会进行绘制Decoration,那么会去调用onDraw和onDrawOver方法,那么这边我们其实只要去重写onDraw和getItemOffsets这两个方法就可以实现啦。然后LayoutManager会进行Item布局的时候,回去调用getItemOffset方法来计算每个Item的Decoration合适的尺寸,下面我们来具体实现一个Decoration。TestDecoration.java

public class TestDecoration extends RecyclerView.ItemDecoration {  
    //采用系统内置的风格的分割线  
    private static final int[] attrs=new int[]{android.R.attr.listDivider};  
    private Drawable mDivider;  
   
    public TestDecoration(Context context) {  
        TypedArray typedArray=context.obtainStyledAttributes(attrs);  
        mDivider=typedArray.getDrawable(0);  
    }  
   
    /** 
     * 进行自定义绘制 
     * @param c 
     * @param parent 
     * @param state 
     */  
    @Override  
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {  
        int top=parent.getPaddingTop();  
        intbottom=parent.getHeight()-parent.getPaddingBottom();  
        int childCount=parent.getChildCount();  
        for(int i=0;i<childCount;i++){  
            View child=parent.getChildAt(i);  
            RecyclerView.LayoutParams layoutParams=(RecyclerView.LayoutParams)child.getLayoutParams();  
            intleft=child.getRight()+layoutParams.rightMargin;  
            intright=left+mDivider.getIntrinsicWidth();  
           mDivider.setBounds(left,top,right,bottom);  
            mDivider.draw(c);  
        }  
    }  
   
    @Override  
    public void getItemOffsets(Rect outRect,View view, RecyclerView parent, RecyclerView.State state) {  
       outRect.set(0,0,mDivider.getIntrinsicWidth(),0);  
    }  
} 


我这边实例中采用系统主题(android.R.attr.listDivider)来设置成分隔线的,然后来获取尺寸,位置进行setBound(),绘制,接着通过outRect.set()来设置绘制整个区域范围,最后不要忘记往RecyclerView中设置该自定义的分割线,

recyclerView_one.addItemDecoration(newTestDecoration(this));  


上面的分割线效果只是垂直画了分割线,但是我们水平方向也要进行画分割线,那么我们下面对于自定义的Decoration进行改进,AdvanceDecoration.java就出现啦。

5.RecyclerView高级用户(监听事件处理)

我们知道在ListView使用的时候,该控件给我们提供一个onItemClickListener监听器,这样当我们的item发生触发事件的时候,会回调相关的方法,以便我们方便处理Item点击事件。对于RecyclerView来讲,非常可惜的时候,该控件没有给我们提供这样的内置监听器方法,不过我们可以进行改造实现。我们先来看一下之前我们写得TestRecyclerAdapter中的onCreateViewHolder()方法中的代码:

public ViewHolder onCreateViewHolder(ViewGroupparent, int viewType) {  
       Viewview=mInflater.inflate(R.layout.item_recycler_layout,parent,false);  
       //这边可以做一些属性设置,甚至事件监听绑定  
       //view.setBackgroundColor(Color.RED);  
       ViewHolder viewHolder=newViewHolder(view);  
       return viewHolder;  
   }  


该方法创建一个ViewHolder,其中承载的就是每一项Item View视图,那么我们可以在view创建出来之后给它进行添加相应的属性或者监听方法,例如:背景颜色,大小,以及点击事件。既然可以这样解决,OK,我们给View添加一个onClickListener监听器,然后点击的时候回调onClick()方法。同时我们需要自定义一个类似于onItemClickListener()的监听器来处理。  

   /** 
     * 自定义RecyclerView 中item view点击回调方法 
     */  
    interface OnRecyclerItemClickListener{  
        /** 
         * item view 回调方法 
         * @param view  被点击的view 
         * @param position 点击索引 
         */  
        void onItemClick(View view, intposition);  
    }  


然后声明以及Adapter初始化的时候传入进去:

public  TestRecyclerAdapter(Contextcontext,OnRecyclerItemClickListener onRecyclerItemClickListener){  
        ……..  
       this.onRecyclerItemClickListener=onRecyclerItemClickListener;  
}  


然后我们在onClick回调方法中调用OnRecyclerItemClickListener接口的方法。

view.setOnClickListener(new View.OnClickListener() {  
         @Override  
         public void onClick(View v) {  
            if(onRecyclerItemClickListener!=null){  
                onRecyclerItemClickListener.onItemClick(view, (int)view.getTag());  
             }  
         }  
});  


上面的onItemClick中第二个参数的position,采用view.getTag的方法获取,那么我们就需要在onBindViewHolder()方法中设置一个tag了.

public voidonBindViewHolder(ViewHolder holder, int position) {  
       holder.item_tv.setText(mTitles[position]);  
        holder.itemView.setTag(position);  
}  


最后我们在外部使用一下接口:

mAdapter = new TestRecyclerAdapter(this, new TestRecyclerAdapter.OnRecyclerItemClickListener() {  
            @Override  
            public void onItemClick(View view,int position) {  
               Toast.makeText(RecyclerViewTestActivity.this, "点击了第"+position+"项", Toast.LENGTH_SHORT).show();  
            }  
});  


6.RecyclerView数据添加删除处理

讲了以上RecyclerView中各种用户,处理之后,现在我们来看一下当数据发生变化之后的处理。例如我们在使用ListView的时候,当数据发生变化的时候可以通过notifyDatasetChange()来刷新界面。
对于RecyclerView控件来讲,给我们提供更加高级的使用方法notifyItemInserted(position)和notifyItemRemoved(position)

我们可以在TestRecyclerAdapter中添加数据新增和数据删除的方法如下:

//添加数据  
 public void addItem(String data, intposition) {  
     mTitles.add(position, data);  
     notifyItemInserted(position);  
 }  
 //删除数据  
 public void removeItem(String data) {  
     int position = mTitles.indexOf(data);  
     mTitles.remove(position);  
     notifyItemRemoved(position);  
 }  


然后我们在Activity中进行调用即可:

//添加数据  
mAdapter.addItem("additem",5);  
//删除数据  
mAdapter.removeItem("item4");


在运行之前我们不要忘记RecyclerView给提供了动画设置,我这边就直接采用了默认动画,设置方法如下:

//添加默认的动画效果  
recyclerView_one.setItemAnimator(new DefaultItemAnimator()); 




转自:http://www.2cto.com/kf/201511/450814.html
  • 大小: 29.6 KB
  • 大小: 21.8 KB
分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    Android代码-Android RecyclerView演示

    RecyclerView使用详解(一) Android RecyclerView part 2 blog --&gt;RecyclerView使用详解(二) Android RecyclerView part 3 blog --&gt;RecyclerView使用详解(三) Update ---20150615--- ...

    Android RecyclerView网格布局(支持多种分割线)详解(2)

    上篇Android RecyclerView 详解(1)—线性布局 记录了下RecyclerView的使用方法,并且讲述了线性布局列表的使用方法,在此基础上加上了万能分割线,支持颜色分割线和图片分割线,同时支持对分割线设置线宽。 这篇...

    Android无限循环RecyclerView的完美实现方案

    Android 无限循环 RecyclerView 实现方案详解 Android 无限循环 RecyclerView 的实现方案是 Android 开发中常见的需求,特别是在实现无限循环的横向列表时。下面我们将详细介绍两种常见的实现方案,并对其进行比较...

    Android RecyclerView 基础知识详解

    Android RecyclerView 是Android开发中的一个核心组件,它在Android Lollipop(API 21)及以后的版本中引入,作为ListView和GridView的替代品。RecyclerView的设计目标是提高性能、可定制性和用户体验,尤其是在处理...

    Android RecyclerView使用方法详解

    Android RecyclerView使用方法详解 Android RecyclerView是Android Support Library中提供的一个新的列表组件,旨在取代传统的ListView。 RecyclerView提供了更好的性能和灵活性,能够满足复杂的列表需求。 ...

    Android RecyclerView基本使用详解

    在Android开发中,RecyclerView是一个非常重要的组件,它用于高效地展示大量数据集合,尤其是在滚动时。与传统的ListView相比,RecyclerView提供了更高的性能和更多的定制选项。本文将深入解析RecyclerView的基本...

    ndroid之 RecyclerView,CardView 详解和相对应的上拉刷新下拉加载

    Android之 RecyclerView,CardView 详解和相对应的上拉刷新下拉加载,博客地址:http://blog.csdn.net/dickyqie/article/details/54913289

    Android RecyclerView 复用错乱通用解法详解

    Android RecyclerView 复用错乱通用解法详解 Android RecyclerView 是一个非常流行的UI控件,用于展示大量内容。在实际开发中,我们经常会遇到 RecyclerView 的复用错乱问题。本文将详细介绍RecyclerView 复用错乱...

    Android中RecyclerView实现分页滚动的方法详解

    下面介绍通过 RecyclerView 实现该需求的实现过程(效果图如下)。 二、功能实现 2.1 OnTouchListener 记录当前开始滑动位置 要实现翻页滑动首先我们要确定是向前翻页还是向后翻页,这里通过记录开始翻页前当前的...

    android 新组件RecyclerView及CardView 使用详解

    在Android开发中,RecyclerView和...总之,理解并熟练掌握RecyclerView和CardView的使用,对于提高Android应用的界面设计和用户体验至关重要。通过不断实践和探索,开发者可以创造出更多富有创意和功能丰富的界面。

    Android RecyclerView详解及简单实例

    【Android RecyclerView详解】 Android RecyclerView 是一个强大的视图组件,它在Android 5.0(API级别21)中被引入,用于替代ListView等传统的列表视图。RecyclerView的主要优点在于其高度可定制化和高效的内存...

    RecyclerView使用详解-示例源码

    在Android开发中,RecyclerView是一个非常重要的组件,它用于展示可滚动的数据集,如列表或网格。RecyclerView替代了早先的ListView,提供了更高效、更灵活的界面更新机制。本示例源码是针对RecyclerView的详细使用...

    浅谈Android RecyclerView 间距全适配

    Android RecyclerView 间距全适配详解 Android RecyclerView 间距全适配是 Android 开发中一个常见的问题,特别是在使用 RecyclerView 时,如何设置间距成为一个重要的考虑因素。在本文中,我们将详细介绍 Android ...

Global site tag (gtag.js) - Google Analytics