首先在念书 RecyclerView 的源码此前,前几天带来的是那五个大约拥有同等的功能的比较使用

ListView,就像其名,是用来浮现列表的一种View,而RecycleView,是其的加强版,明日带来的是那多个大概所有相同的功效的自查自纠使用

ListView:

1.在布局文件中行使ListView,并为其定义一个id,方便大家今后的调用,宽高与父控件相同

2.备选数据,将数据拉长到ArrayAdapter适配器当中

3.在Activity的java文件中行使findviewbyid找到ListView实例,为其设置艾达pter

4.完结ListView的item项点击事件,直接利用Listview定义的setitemonClick方法就行了

 

此处最为重大的一步其实是第二步,大家可以看到下边的代码,定义了一组String类型的数组,之后创建ArrayAdapter适配器,注意String,是一个泛型,前边的构造函数里的参数分别为上下文android.R.Layout.simple_list_item
1
是安卓系统给的一个item布局,最终一项是String数组,也就是多少,之后寻找ListView的实例,调用setAdapter方法设置适配器

  public class MainActivity extends AppCompatActivity {
        private String[] data = {"Apple" ,"Banana","Orange","WatermeLon"
                "Pear","Grape","Pineapple","Strawberry","Cherry","Mango",
                "Apple","Banana","Orange" ,"Watermelon" ,"Pear" ,"Grape",
                "Pineapple","Strawberry","Cherry","Mango"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity.main);
        ArrayAdapter<String> adapter = new ArrayAdapter<String(MainActivity.this, android.R.Layout.simple_list_item 1, data);
        ListView listView = (ListView) findViewById(R.id.list _view);
        listView.setAdapter(adapter);
    }
}

那是一个简易的例证,不过,我们通晓第四个参数是安卓提供的一个item布局,这些布局过于简单,大家想要完成一个自定义布局咋做?大家要求改造一下ArrayAdapter这一个适配器

上边便是自定义布局并采纳的手续:

1.创立一个item的布局,也就是大家的自定义布局

图片 1

自身定义了四个各占一半的textview,记得根标签的高使用wrap_content

 

2.概念一个T类,作为适配器的泛型,(类似事先的String),里面需求一个构造方法,成员变量和get方法

图片 2

不晓得怎么会有警示,用的public,可以正常使用,假使改为其余,别的那边调用就会出错了

 

3.创办一个适配器类,使其继承ArrayAdapter<T>(T就是第二步定义的类),里面需求一个构造方法,还亟需复写getView方法

 图片 3

 

4.准备数据,将数据增加到第三步的适配器类中,之后与地点所说的手续一样,找到Listview的实例,设置适配器

 图片 4

 

 效果

图片 5

 

 

3) RecyclerView item 添加移除动画

RecyclerViewAdapter 的 notifyItemInserted(position) 和
notifyItemRemoved(position) 方法默认添加了丰硕
和移除 item 时的卡通片,在意!!!在增进多少时要将 item
中度的集纳同时加上数据,要不然会报 数组越界分外

源码:
https://github.com/renxuelong/RecycleViewDemo

 

 

 

 

 

 

 

 

 

先从ListView说起吧

三、总结

浅析了动用 RecyclerView 的拔取和原理,大家再来整理一下做一个总括

伊始化 RecyclerView 并为其安装 Adapter 之后,就可以为其安装
LayoutManager 来确定 RecyclerView 怎么显得了,之后 LayoutManager
会依据数据量的分寸和 RecyclerView 的半空中尺寸通过循环来填充
RecyclerView。每回循环都会从 Recycler 中获得须要显示的 View,Recycler
中经过打消 ViewHolder 的汇集或者 Adapter 的 createViewHolder 方法取得
ViewHolder,然后调用 mAdapter 的 bindViewHolder 为 ViewHolder 中的
itemView 设置要出示的多寡。拿到要出示的 View 后 LayoutManager 会将该
View
拉长到 RecyclerView 中并根据 View 的轻重和 RecyclerView
剩余空间、布局形式等规定 View 在 RecyclerView
中的坐标,绘制完结之后界面上就会来得我们抬高的 item 了

同 ListView 一样,在滑行爆发时会回收已经滑出显示屏的 item 对应的 ViewHoler
到 Recycler 中,那样在无数条数据时也不会成立大气的
ViewHolder,保险了程序的特性。

ListView:

1.在布局文件中采纳ListView,并为其定义一个id,方便大家未来的调用,宽高与父控件相同

2.准备数据,将数据增加到ArrayAdapter适配器当中

3.在Activity的java文件中采取findviewbyid找到ListView实例,为其安装Adapter

4.贯彻ListView的item项点击事件,直接动用Listview定义的setitemonClick方法就行了

 

此地最为关键的一步其实是第二步,大家得以看到上边的代码,定义了一组String类型的数组,之后创设ArrayAdapter适配器,注意String,是一个泛型,前面的构造函数里的参数分别为上下文android.R.Layout.simple_list_item
1
是安卓系统给的一个item布局,最后一项是String数组,也就是数额,之后寻找ListView的实例,调用setAdapter方法设置适配器

  public class MainActivity extends AppCompatActivity {
        private String[] data = {"Apple" ,"Banana","Orange","WatermeLon"
                "Pear","Grape","Pineapple","Strawberry","Cherry","Mango",
                "Apple","Banana","Orange" ,"Watermelon" ,"Pear" ,"Grape",
                "Pineapple","Strawberry","Cherry","Mango"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity.main);
        ArrayAdapter<String> adapter = new ArrayAdapter<String(MainActivity.this, android.R.Layout.simple_list_item 1, data);
        ListView listView = (ListView) findViewById(R.id.list _view);
        listView.setAdapter(adapter);
    }
}

那是一个简短的事例,不过,我们精通第三个参数是安卓提供的一个item布局,那一个布局过于不难,大家想要达成一个自定义布局如何做?大家需要改造一下ArrayAdapter这么些适配器

下边便是自定义布局并应用的步调:

1.创设一个item的布局,也就是大家的自定义布局

图片 6

自己定义了多个各占一半的textview,记得根标签的高使用wrap_content

 

2.定义一个T类,作为适配器的泛型,(类似事先的String),里面必要一个构造方法,成员变量和get方法

图片 7

不晓得怎么会有警示,用的public,可以正常使用,借使改为别的,此外那边调用就会出错了

 

3.开立一个适配器类,使其继承ArrayAdapter<T>(T就是第二步定义的类),里面需求一个构造方法,还亟需复写getView方法

 图片 8

 

4.备选数据,将数据增进到第三步的适配器类中,之后与地点所说的步骤一样,找到Listview的实例,设置适配器

 图片 9

 

 效果

图片 10

 

 

 

 

 

 

 

 

 

 

 

先是在就学 RecyclerView 的源码从前,提议先阅读 ListView
的源码分析
,之后学 RecyclerView
会更快更自在。
传送门在这里
http://www.jianshu.com/p/ad621b49735e

 RecycleView:

是因为这些是Android团队新推出的,须求大家抬高依赖才可以应用,记得点击sync
now

图片 11

 

 使用手续:

1.在布局文件中行使RecyclerView,定义id,宽高与上空相同

2.准备RecyclerView的子项item布局,之后要在适配器类中应用,这里就不在赘述

3.定义个泛型类,如此前在ListView中所说的T类,适配器的泛型

3.定义一个适配器T类,使其后续RecyclerView.Adapter<T.ViewHolder>(ViewHolder是T类中的一个里面类),要求一个构造方法接收数据源,复写三个主意

图片 12

RecyclerAdapter是继承RecyclerView.Adapter<RecyclerAdapter.ViewHolder>

其一尖括号里的本来应该是RecyclerView.ViewHolder,不过大家在RecyclerAdapter里定义了一个里面类ViewHolder,使其继承了RecyclerView.ViewHolder,所以大家就可以在尖括号里直接调用内部类

我们先来看一下ViewHolder这一个里面类,它其中有八个TextView的分子变量,之后,添加一个构造方法,参数是一个View,为这一个多少个textview通过findviewbyid找到实例

我们来看RecycleAdapter那么些类,在上马大家就扬言了一个List的积极分子变量students,之后,添加构造方法,传入一个LIst,将其赋值给RecycleAdapter的分子变量students

 

后来需求复写多少个法子,OnCreateViewHolder,onBindViewHolder,getItemCount

图片 13

onCreateViewHolder方法里面,首先就是透过LayoutInflater.from()方法接收一个context,之后,再经过inflate将item布局放进总布局中,之后再将这一个view作为参数传到ViewHolder中去,同时,重返一个ViewHolder

onBindViewHolder方法,由list的get方法,得到list里面的某个对象,之后,由holder调用四个TextView的setText方法举办安装,举一反三,要是是imageview的话,同样可以应用setresource设置其出示的图样,设置的参数,大家可以直接由Student类中的get方法赢得

 getItemCount
就是取得全套item的数据,那里item数量实在就是list中的项目,直接重回其的size就行了

4.预备数据,添加到适配器中

5.创办一个搭架子管理器LayoutManager,便于RecycleView设置布局,那里布局管理器有二种

一种的像LIstView的垂直排列,LinearlayoutManager

图片 14

咱俩也足以将其改为水平排列,只需调用linearLayoutManger的setOrientation,设置为LinearLayoutManager.HORIZONTAL

图片 15

还有GiidLayout网格布局
StaggerGildLayoutManager瀑布流布局,使用办法如上,不过,参数有所不一致,想询问越多请转百度

 

6.通过findviewbyid方法找到RecycleView的实例,为其设置LayoutManager,设置艾达pter

图片 16

 7.设置onClick方法,RecycleView里没有onClick方法,必要大家温馨写,在何地写吧?在RecycleAdapter中的onBindViewHolder方法中

图片 17

大家用Viewholder来找到子项,为其安装一个onClickListener,之后,为其设置onClick事件处理

上边那是比较简单的一种,还有任何二种格局,我在那也不一一测试,感兴趣的话可以友善探讨研究

参考地址:http://blog.csdn.net/RaphetS/article/details/51254538

 

越多的RecycleView高级使用,请参考上面的地点

http://blog.csdn.net/skykingf/article/details/50827141

http://www.jianshu.com/p/58ca20e1a5d6

 RecycleView:

由于这么些是Android团队新生产的,需求大家添加器重才得以行使,记得点击sync
now

图片 18

 

 使用手续:

1.在布局文件中利用RecyclerView,定义id,宽高与上空相同

2.预备RecyclerView的子项item布局,之后要在适配器类中动用,那里就不在赘述

3.概念个泛型类,如以前在ListView中所说的T类,适配器的泛型

3.概念一个适配器T类,使其后续RecyclerView.Adapter<T.ViewHolder>(ViewHolder是T类中的一个之中类),须求一个构造方法接收数据源,复写三个措施

图片 19

RecyclerAdapter是继承RecyclerView.Adapter<RecyclerAdapter.ViewHolder>

本条尖括号里的当然应该是RecyclerView.ViewHolder,不过大家在Recycler艾达pter里定义了一个之中类ViewHolder,使其连续了RecyclerView.ViewHolder,所以大家就能够在尖括号里直接调用内部类

俺们先来看一下ViewHolder那些里面类,它其中有八个TextView的成员变量,之后,添加一个构造方法,参数是一个View,为那个四个textview通过findviewbyid找到实例

俺们来看RecycleAdapter那么些类,在起来我们就宣称了一个List的分子变量students,之后,添加构造方法,传入一个LIst,将其赋值给RecycleAdapter的成员变量students

 

自此要求复写多个点子,OnCreateViewHolder,onBindViewHolder,getItemCount

图片 20

onCreateViewHolder方法里面,首先就是通过LayoutInflater.from()方法接收一个context,之后,再经过inflate将item布局放进总布局中,之后再将以此view作为参数传到ViewHolder中去,同时,重返一个ViewHolder

onBindViewHolder方法,由list的get方法,获得list里面的某部对象,之后,由holder调用多少个TextView的setText方法举办安装,举一反三,即使是imageview的话,同样能够采纳setresource设置其出示的图形,设置的参数,我们得以一直由Student类中的get方法得到

 getItemCount
就是获取任何item的多寡,那里item数量实在就是list中的项目,直接回到其的size就行了

4.备选数据,添加到适配器中

5.创设一个搭架子管理器LayoutManager,便于RecycleView设置布局,那里布局管理器有二种

一种的像LIstView的垂直排列,LinearlayoutManager

图片 21

咱俩也足以将其改为水平排列,只需调用linearLayoutManger的setOrientation,设置为LinearLayoutManager.HORIZONTAL

图片 22

再有GiidLayout网格布局
StaggerGildLayoutManager瀑布流布局,使用办法如上,不过,参数有所不相同,想领悟越多请转百度

 

6.通过findviewbyid方法找到RecycleView的实例,为其设置LayoutManager,设置Adapter

图片 23

 7.设置onClick方法,RecycleView里没有onClick方法,必要大家自己写,在哪儿写吧?在RecycleAdapter中的onBindViewHolder方法中

图片 24

大家用Viewholder来找到子项,为其设置一个onClickListener,之后,为其安装onClick事件处理

上边那是比较不难的一种,还有别的三种艺术,我在这也不一一测试,感兴趣的话可以自己研究切磋

参照地址:http://blog.csdn.net/RaphetS/article/details/51254538

 

更加多的RecycleView高级使用,请参见上边的地址

http://blog.csdn.net/skykingf/article/details/50827141

http://www.jianshu.com/p/58ca20e1a5d6

1、创建 Adapter

  1. 新建类继承
    RecyclerViewAdapter<MyRecyclerViewAdapter.MyViewHolder>,
    泛型指定为 MyRecyclerViewAdapter 的其中类
    MyRecyclerViewAdapter.MyViewHolder,
  2. 连忙键成立自定义内部类 MyViewHolder 类
  3. 快捷键修改自定义的MyViewHolder 类继承自 V7 包的
    RecyclerView.ViewHolder
  4. 重写MyViewHolder 的一个参数的构造方法
  5. 飞速键导入 RecyclerViewAdapter的抽象方法

先从ListView说起吧

ListView,如同其名,是用来突显列表的一种View,而RecycleView,是其的加强版,昨天带来的是那多少个大概拥有同样的作用的对照使用

1. setAdapter 方法

RecyclerView 的 setAdapter 方法中同 ListView 一样,会使用观看者方式,将
RecyclerView 作为观看者,Adapter 作为被观望者,在 Adapter 中一个会见添加
RecyclerView,在调用 Adapter 的 notify 种类措施时,会调用 RecyclerView
中的相应措施完成刷新数据

1) ViewHolder 类创造步骤

  1. 先是表明须要体现的控件
  2. 在构造方法中,通过构造方法的参数 View ,由 View.findViewById()
    方法发轫化各控件

二、RecyclerView 源码分析

2) Adapter 类已毕步骤

  1. 重写 onCreateViewHolder() ,调用 MyViewHolder 的参数为 View
    的构造方法创造
    MyViewHolder 对象,该 View 对象通过 LayoutInflater 加载 item 布局的
    xml 文件得到,然后将 MyViewholder 作为重返值再次来到。
  2. 重写 onBindViewHolder() ,调用方法中的 ViewHolder 对象,以及由参数
    position
    取得要实际的多寡, 将数据绑定至 ViewHolder
  3. 重写 getItemCount() , 重临数据集合的 size

2、RecycleView 配置步骤

  1. 初始化 RecyclrView 对象
  2. 为 RecyclerView 设置布局管理器,new 一个 LinearLayoutManager可以经过
    setOrientation 设置水平或垂直滚动,默许的是笔直滚动的
  3. 初始化 RecyclerViewAdapter
  4. 为 RecyclerView 设置 Adapter

1) RecyclerView 设置 ItemClickListener/ItemLongClickListener

  1. 在 Adapter 中定义 Listener 接口,定义监听方法,在 Adapter 中定义
    Listener 对象和 setListener 的措施
  2. 在 onBindViewHolder() 方法中判断固然 Listener 对象即使不为空就为
    viewHolder.itemView
    加上 onClickListener() 方法,在 onClick() 方法中调用 Listener
    接口中的监听方法
  3. 假定须求添加监听器,就在 RecyclerViewAdapter 对象初阶化后调用
    setListener() 方法

2. setLayoutManager 方法

不相同于 ListView 自己完结 item 的排列和出示,RecyclerView
将这一职分交给了 LayoutManager ,由 LayoutManager 负责 item
的排列,尤其解耦,同一个 RecyclerView 可以来得分化的成效

RecyclerView 的 setLayoutManager 方法中,会调用 requestLayout
方法,我们领悟 requestLayout 会申请重新测量、布局、绘制整个经过,在
layout 进程中会调用 onLayout 方法,onLayout 方法中,会调用
dispatchLayout 方法,其中会调用对应 LayoutManager 的 onLayoutChildren
方法

// RecyclerView
public void setLayoutManager(LayoutManager layout) {
    ...
    mLayout = layout;
    requestLayout();
}

//RecyclerView
private void dispatchLayoutStep1() {
    ...
    mLayout.onLayoutChildren(mRecycler, mState);
    ...
}

出于 LayoutManager 的 onLayoutChildren
方法是空方法,其子类具体落到实处了该方法,以 LinearLayoutManager 为例

// LinearLayoutManager
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State         state) {
    ...
    fill(recycler, mLayoutState, state, false);
    ...
}

// LinearLayoutManager
int fill(RecyclerView.Recycler recycler, LayoutState layoutState,
        RecyclerView.State state, boolean stopOnFocusable) {

    // 计算可用宽高

    // 开启循环向其中添加 item
    // 1.通过 layoutChunk 方法添加一个 item 
    // 2. 计算偏移量
    // 3. 计算剩余空间,如果还有剩余空间则继续循环,如果超出空间则跳出循环
}

// LinearLayoutManager
void layoutChunk(RecyclerView.Recycler recycler, RecyclerView.State state,
        LayoutState layoutState, LayoutChunkResult result) {

    // 1. 获取要显示的 item
    View view = layoutState.next(recycler);

    // 2. 获取 LayoutParams
    LayoutParams params = (LayoutParams) view.getLayoutParams();        

    // 3. 将 item 添加到 RecyclerView addView --> recyclrView.add()
    addView(view);        

    // 4. 测量 item 
    measureChildWithMargins(view, 0, 0);

    // 5. 根据 item 的大小、装饰大小、布局方向(水平垂直)、RecyclerView 中已经占用空间 等信息计算 item 在 RecyclerView 中的坐标

    // 6. 根据上一步得到的坐标布局 item
    layoutDecorated(view, left + params.leftMargin, top + params.topMargin,
                right - params.rightMargin, bottom - params.bottomMargin);
}

// LayoutManager
public void layoutDecorated(View child, int left, int top, int right, int bottom) {
    final Rect insets = ((LayoutParams) child.getLayoutParams()).mDecorInsets;

    // 布局子 View 确定子 View 在 父 View 的坐标
    child.layout(left + insets.left, top + insets.top, right - insets.right,
            bottom - insets.bottom);
}

有地点代码以及注释可见,在 LayoutManager 的 onLayoutChildren 中,为
RecyclerView 填充了 item,并经过测量和布局进程确定了每一个 item 在
RecyclerView 中的地方。

地点代码中还有一个很重点的章程,ayoutState.next(recycler)
方法,刚才一笔带过,现在再来看那些获得 item 的机要方法

// LayoutState
View next(RecyclerView.Recycler recycler) {
    if (mScrapList != null) {
        return nextViewFromScrapList();
    }
    final View view = recycler.getViewForPosition(mCurrentPosition);
    mCurrentPosition += mItemDirection;
    return view;
}

// Recycler 用来存放回收的 ViewHolder 以及提供 item
public final class Recycler {
    final ArrayList<ViewHolder> mAttachedScrap = new ArrayList<ViewHolder>();
    private ArrayList<ViewHolder> mChangedScrap = null;

    final ArrayList<ViewHolder> mCachedViews = new ArrayList<ViewHolder>();

    private final List<ViewHolder>
            mUnmodifiableAttachedScrap = Collections.unmodifiableList(mAttachedScrap);
    ...

    // 获取 item 的 View 对象的方法
    View getViewForPosition(int position, boolean dryRun) {
        // 1. 从废弃集合中获取需要的 ViewHolder
        // 2. 如果从废弃的集合中没有获取到,则通过 Adapter 创建
        if (holder == null) {
            holder = mAdapter.createViewHolder(RecyclerView.this, type);
        }

        // 通过 mAdapter 设置要显示的 item 的 View 的显示数据
        mAdapter.bindViewHolder(holder, holder.mPosition);

        final ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
        final LayoutParams rvLayoutParams;
        if (lp == null) {
            // 设置默认 LayoutParams
            rvLayoutParams = (LayoutParams) generateDefaultLayoutParams();
            holder.itemView.setLayoutParams(rvLayoutParams);
        } else if (!checkLayoutParams(lp)) {
            rvLayoutParams = (LayoutParams) generateLayoutParams(lp);
            holder.itemView.setLayoutParams(rvLayoutParams);
        } else {
            rvLayoutParams = (LayoutParams) lp;
        }
        rvLayoutParams.mViewHolder = holder;
        rvLayoutParams.mPendingInvalidate = fromScrap && bound;
        // 返回 item 要显示的 View
        return holder.itemView;

    }
}

先看率先步,通过 Recycler 对象的 getViewForPosition 方法得到item,Recycler 中定义了众多集结,用来存放在被回收的 ViewHolder
对象。这几聚众的效益相近 ListView 的 RecycleBin 中的屏弃 item 集合,在
ListView 中是存放在抛弃的 item 布局,并在 get 方法少校舍弃的 item
重返。而在 Recycler 中存放的是甩掉的 ViewHolder

从地点源码中可以见见,getViewForPosition 方法会先从摒弃的从扬弃的
ViewHolder 集合中取得 ViewHolder,若是没有对号入座的抛弃 ViewHolder 则透过
mAdapter.createViewHolder 方法成立 ViewHolder
,还记得这些法子呢,这一个办法是亟需大家自定义 Adapter
时重写的不二法门,这几个点子中根据如今地方 position 创设了 ViewHolder 并再次回到。

任由是从屏弃的聚集中获取到的 ViewHolder 依旧从 mAdapter
中成立的,之后都会调用 mAdapter.bindViewHolder
方法,那么些主意也是亟需大家定义 Adapter 时重写的,依照 ViewHolder
和当下地方 position 的数目伊始化 ViewHolder 中 itemView 的来得

终极在 ViewHolder 的 itemView 设置 LayoutParams 后将 holder.itemView
重回,也就是回到当前 item 处须求出示的 View

Recycler 获取 item 要显示 View 的步骤

  1. 从放弃的 ViewHolder 集合中得到
  2. 若是没有对号入座的舍弃 ViewHolder 则透过 mAdapter 成立 ViewHolder
  3. 据悉 ViewHolder 和当前义务 position 的数量开首化 ViewHolder 中
    itemView 的突显
  4. 返回 View

一、使用

导包: compile ‘com.android.support:recyclerview-v7:23.4.0’

2) RecyclerView 的布局管理器

  1. LinearLayoutManager ListView 型 可以安装水平或垂直滑动

    LinearLayoutManager layoutManager = new LinearLayoutManager(this);
    layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
  1. GridLayoutMAnager GridView 型
    可以设置水平或垂直排列,最后一个参数表示是还是不是反向排列,即数据从尾到头

    GridLayoutManager layoutManager = new GridLayoutManager(this, 4, GridLayoutManager.HORIZONTAL, false);
  1. StaggeredGridLayoutManager 瀑布流 onBindViewHolder() 方法中为每一个
    item
    设置差异中度后,即落实瀑布流效果,可以在一个尺寸为与数码集合长度相同的集结中保留每一个
    item 的万丈,然后在 onBindViewHolder 方法中为 item
    设置高度时就可以在那一个集合中一贯取值。

StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL);

相关文章