RecyclerView 解析
2016-02-17 17:08
357 查看
在项目中使用RecyclerView已经有很长一段时间了,现在结合RecyclerView源码分析总结一下。
RecyclerView:是support-v7包中的新组件,用于在有限的窗口显示大量的数据,项目中之前使用到的ListView、GridView等可以轻易的替换为RecyclerView,这里强力推荐大家使用RecyclerView。
RecyclerView直接继承于ViewGroup,提供很多方便实用的public方法,提供有很多内部类,基本代码结构如下:
下面挑选一些重要的内部类简单介绍一下:
RecyclerView.Adapter: 提供具体应用数据和RecyclerView展示的条目View的绑定。
这里的Adapter和以往ListView、GridView等使用到的Adapter完全不同。ListView、GridView等View的Adapter这里不做详细介绍。
RecyclerView.Adapter的代码结构如下:
阅读RecyclerView的源码,发现其Adapter没有任何默认实现,在使用的时候需要自己实现Adapter,三个抽象函数是必须要实现的,getItemViewType函数可根据实际需求进行重载,如果RecyclerView的Item有多种类型,则需要重载,否则默认实现方式就可以了。
RecyclerView.ViewHolder
代表RecyclerView的每一个ItemView,通过它保存Item中使用到的控件的引用来减少findViewById的调用,RecyclerView管理ItemView的重用回收等也是通过存贮iewHolder来实现。
正如源码所示,itemView 已经以public 方式存放了,自定义ViewHolder 时,不再需要在重复保存itemView ,项目中需要对itemView 操作(如设置背景、添加事件等),直接使用就可以了。
实际使用的时候,使用自定义的ViewHolder 来替换RecyclerView.Adapter里面的泛型VH。
RecyclerView.LayoutManager
LayoutManager 负责测量和放置itemView 在RecyclerView合适的位置,决定不可见的itemView 的回收方式。通过改变LayoutManager ,RecyclerView可以实现垂直滚动列表,网格,瀑布流,水平滚动列表等等,使用方式非常灵活,高效。android.support.v7库已经默认实现了几种LayoutManager ,项目使用中有特殊需求也可以自定义LayoutManager 。
自定义LayoutManager 需要分别重载和实现如下两个函数:
android.support.v7库提供的LayoutManager 默认实现有如下几种:
其中,LinearLayoutManager提供类似ListView的功能,可以实现水平或垂直列表,默认为垂直列表。
GridLayoutManager 提供类似GradView的功能,实现表格布局。
StaggeredGridLayoutManager 实现瀑布流。
RecyclerView.ItemDecoration
ItemDecoration可以用来添加items分割线,让item高亮,给组添加边界等等。
RecyclerView.ItemAnimator
ItemAnimator 提供Item添加、删除时的动画效果。
android.support.v7 提供了一个默认实现DefaultItemAnimator,如果没有设置动画效果,RecyclerView使用默认的DefaultItemAnimator。实际使用的时候可以扩展ItemAnimator,实现需要的,符合要求的,非常炫的动画效果。
RecyclerView.RecycledViewPool
RecycledViewPool 可以实现多个RecyclerViews共享Views,有效减少创建ViewHolder的开销,避免垃圾回收。实际项目使用中,如果你没有提供RecycledViewPool,RecyclerViews也会自己默认自动创建一个。
查看RecyclerView的源码
通过上述源码,发现RecycledViewPool使用也非常简单,只需获取任意一个RecyclerView创建的RecycledViewPool,然后分别设置到其他RecyclerView,就可实现共享。
RecyclerView 简单使用如下:
总结,RecyclerView代码耦合非常低,具有如下优点:
1、RecyclerView里View的布局完全由LayoutManager管理,布局灵活高效,本身提供了常用布局,也可以简单的通过扩展实现想要的布局方式;
2、RecyclerView对View的回收重用管理比传统ListView、GradeView等更加高效、灵活;
3、对ItemView的添加装饰如设置分割线、背景、高亮等非常灵活、简单;
4、RecyclerView添加ItemView变化(数据增加、删除等)时的动画非常灵活,而且本身默认就提供了动画,也可以扩展实现非常炫的动画效果。
。。。
当然,RecyclerView源码里还有很多细节,实际使用的时候,结合源码,通过扩展RecyclerView,可以实现非常高效、炫丽的List效果。
RecyclerView:是support-v7包中的新组件,用于在有限的窗口显示大量的数据,项目中之前使用到的ListView、GridView等可以轻易的替换为RecyclerView,这里强力推荐大家使用RecyclerView。
RecyclerView直接继承于ViewGroup,提供很多方便实用的public方法,提供有很多内部类,基本代码结构如下:
public class RecyclerView extends ViewGroup implements ScrollingView, NestedScrollingChild { ... final Recycler mRecycler = new Recycler(); private Adapter mAdapter; private LayoutManager mLayout; ... public RecyclerView(Context context) { this(context, null); } public RecyclerView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public RecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); ... } public void setLayoutManager(LayoutManager layout) { ... } ... public void setItemViewCacheSize(int size) { mRecycler.setViewCacheSize(size); } public void addItemDecoration(ItemDecoration decor, int index) { ... } ... public static class RecycledViewPool { ... } public final class Recycler { ... } public abstract static class ViewCacheExtension { ... } public static abstract class Adapter<VH extends ViewHolder> { ... } public static abstract class LayoutManager { ... } public static abstract class ItemDecoration { ... } public static abstract class ViewHolder { ... } public static abstract class ItemAnimator { ... } ... }
下面挑选一些重要的内部类简单介绍一下:
RecyclerView.Adapter: 提供具体应用数据和RecyclerView展示的条目View的绑定。
这里的Adapter和以往ListView、GridView等使用到的Adapter完全不同。ListView、GridView等View的Adapter这里不做详细介绍。
RecyclerView.Adapter的代码结构如下:
public static abstract class Adapter<VH extends ViewHolder> { ... public abstract VH onCreateViewHolder(ViewGroup parent, int viewType); public abstract void onBindViewHolder(VH holder, int position); public final VH createViewHolder(ViewGroup parent, int viewType) { TraceCompat.beginSection(TRACE_CREATE_VIEW_TAG); final VH holder = onCreateViewHolder(parent, viewType); holder.mItemViewType = viewType; TraceCompat.endSection(); return holder; } public final void bindViewHolder(VH holder, int position) { holder.mPosition = position; if (hasStableIds()) { holder.mItemId = getItemId(position); } holder.setFlags(ViewHolder.FLAG_BOUND, ViewHolder.FLAG_BOUND | ViewHolder.FLAG_UPDATE | ViewHolder.FLAG_INVALID | ViewHolder.FLAG_ADAPTER_POSITION_UNKNOWN); TraceCompat.beginSection(TRACE_BIND_VIEW_TAG); onBindViewHolder(holder, position); TraceCompat.endSection(); } public int getItemViewType(int position) { return 0; } public abstract int getItemCount(); ... }
阅读RecyclerView的源码,发现其Adapter没有任何默认实现,在使用的时候需要自己实现Adapter,三个抽象函数是必须要实现的,getItemViewType函数可根据实际需求进行重载,如果RecyclerView的Item有多种类型,则需要重载,否则默认实现方式就可以了。
RecyclerView.ViewHolder
代表RecyclerView的每一个ItemView,通过它保存Item中使用到的控件的引用来减少findViewById的调用,RecyclerView管理ItemView的重用回收等也是通过存贮iewHolder来实现。
public static abstract class ViewHolder { public final View itemView; ... public ViewHolder(View itemView) { if (itemView == null) { throw new IllegalArgumentException("itemView may not be null"); } this.itemView = itemView; } ...
正如源码所示,itemView 已经以public 方式存放了,自定义ViewHolder 时,不再需要在重复保存itemView ,项目中需要对itemView 操作(如设置背景、添加事件等),直接使用就可以了。
实际使用的时候,使用自定义的ViewHolder 来替换RecyclerView.Adapter里面的泛型VH。
RecyclerView.LayoutManager
LayoutManager 负责测量和放置itemView 在RecyclerView合适的位置,决定不可见的itemView 的回收方式。通过改变LayoutManager ,RecyclerView可以实现垂直滚动列表,网格,瀑布流,水平滚动列表等等,使用方式非常灵活,高效。android.support.v7库已经默认实现了几种LayoutManager ,项目使用中有特殊需求也可以自定义LayoutManager 。
自定义LayoutManager 需要分别重载和实现如下两个函数:
public void onLayoutChildren(Recycler recycler, State state) { Log.e(TAG, "You must override onLayoutChildren(Recycler recycler, State state) "); } public abstract LayoutParams generateDefaultLayoutParams();
android.support.v7库提供的LayoutManager 默认实现有如下几种:
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.StaggeredGridLayoutManager;
其中,LinearLayoutManager提供类似ListView的功能,可以实现水平或垂直列表,默认为垂直列表。
public class LinearLayoutManager extends RecyclerView.LayoutManager implements ItemTouchHelper.ViewDropHandler { public LinearLayoutManager(Context context) { this(context, VERTICAL, false); } public LinearLayoutManager(Context context, int orientation, boolean reverseLayout) { setOrientation(orientation); setReverseLayout(reverseLayout); } public LinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { Properties properties = getProperties(context, attrs, defStyleAttr, defStyleRes); setOrientation(properties.orientation); setReverseLayout(properties.reverseLayout); setStackFromEnd(properties.stackFromEnd); } }
GridLayoutManager 提供类似GradView的功能,实现表格布局。
StaggeredGridLayoutManager 实现瀑布流。
RecyclerView.ItemDecoration
ItemDecoration可以用来添加items分割线,让item高亮,给组添加边界等等。
RecyclerView.ItemAnimator
ItemAnimator 提供Item添加、删除时的动画效果。
android.support.v7 提供了一个默认实现DefaultItemAnimator,如果没有设置动画效果,RecyclerView使用默认的DefaultItemAnimator。实际使用的时候可以扩展ItemAnimator,实现需要的,符合要求的,非常炫的动画效果。
RecyclerView.RecycledViewPool
RecycledViewPool 可以实现多个RecyclerViews共享Views,有效减少创建ViewHolder的开销,避免垃圾回收。实际项目使用中,如果你没有提供RecycledViewPool,RecyclerViews也会自己默认自动创建一个。
查看RecyclerView的源码
... void setRecycledViewPool(RecycledViewPool pool) { if (mRecyclerPool != null) { mRecyclerPool.detach(); } mRecyclerPool = pool; if (pool != null) { mRecyclerPool.attach(getAdapter()); } } RecycledViewPool getRecycledViewPool() { if (mRecyclerPool == null) { mRecyclerPool = new RecycledViewPool(); } return mRecyclerPool; } ...
通过上述源码,发现RecycledViewPool使用也非常简单,只需获取任意一个RecyclerView创建的RecycledViewPool,然后分别设置到其他RecyclerView,就可实现共享。
RecyclerView view1 = new RecyclerView(mContext); LinearLayoutManager layout = new LinearLayoutManager(mContext); layout.setRecycleChildrenOnDetach(true); view1.setLayoutManager(layout); RecyclerView.RecycledViewPool recycledViewPool = view1.getRecycledViewPool(); RecyclerView view2 = new RecyclerView(mContext); view2.setRecycledViewPool(recycledViewPool); ... RecyclerView view3 = new RecyclerView(mContext); view3.setRecycledViewPool(recycledViewPool); ...
RecyclerView 简单使用如下:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.my_recyclerview_test); ... RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view); RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(mContext); recyclerView.setLayoutManager(layoutManager); MyRecyclerViewAdapter adapter = new MyRecyclerViewAdapter(); recyclerView.setAdapter(adapter); ... } ... public class MyRecyclerViewHolder extends RecyclerView.ViewHolder { public TextView textView; public MyRecyclerViewHolder(View itemView) { super(itemView); textView = (TextView) itemView.findViewById(R.id.name); } } public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewHolder> { @Override public MyRecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(mContext).inflate(R.layout.item_recyclerview_test_layout, parent, false); MyRecyclerViewHolder viewHolder = new MyRecyclerViewHolder(view); return viewHolder; } @Override public void onBindViewHolder(MyRecyclerViewHolder holder, int position) { holder.textView.setText("hello "+position); } @Override public int getItemCount() { return 3; } }
总结,RecyclerView代码耦合非常低,具有如下优点:
1、RecyclerView里View的布局完全由LayoutManager管理,布局灵活高效,本身提供了常用布局,也可以简单的通过扩展实现想要的布局方式;
2、RecyclerView对View的回收重用管理比传统ListView、GradeView等更加高效、灵活;
3、对ItemView的添加装饰如设置分割线、背景、高亮等非常灵活、简单;
4、RecyclerView添加ItemView变化(数据增加、删除等)时的动画非常灵活,而且本身默认就提供了动画,也可以扩展实现非常炫的动画效果。
。。。
当然,RecyclerView源码里还有很多细节,实际使用的时候,结合源码,通过扩展RecyclerView,可以实现非常高效、炫丽的List效果。
相关文章推荐
- oracle-绑定变量学习笔记(未完待续)
- [置顶] 解决 ecshop 资金管理的权限问题
- (九)建造者模式
- 系统重启后ngix reload不生效原因分析
- vsftpd详解
- 【运动传感器】Madgwick算法(下)
- Kotlin初体验
- 向数据库中添加内容 manageStdInfo.aspx
- ubuntu安装php7.0.3遇到的问题
- JSP
- 任务调度的 Java 实现方法二:quartz
- Virtual Box 复制虚拟机后网络冲突或者无法启动 问题解决方法
- Spring事务配置的五种方式
- 奇怪的电梯解题报告
- PHP之数据分组
- c#中abstract、override、new、virtual、sealed使用和示例
- c语言实现去除代码中的注释
- libcurl - curl_easy_perform 返回值说明
- Orchard基本概念快速理解
- 【运动传感器】Madgwick算法(上)