Android RecyclerView体验(一)- 简介
在网上关于RecyclerView的基本使用方式已经有了比较详细介绍,而且其设计结构也类似于ListView,所以本文将不重点介绍如何使用,在文末的引用中都可以相关内容。这里主要是介绍RecyclerView的基本功能、设计理念,以及系统提供API的情况。
什么是RecycleView
RecyclerView是在Android L(也就是后来的Lollipop)中新加入的一种ViewGroup。但因为它使以support-v7库的形式加入到Android系统中,所以不仅仅是Lollipop版本以后的Android系统可以使用,只要系开发项目中引入这个库就在任意API级别中使用。
单从呈现效果来看RecyclerView和ListView、GridView并没有大多的差别。
不过它的“flexible”并不单单指它可以在ListView和GridView之间随意互相切换,更在于它可以创造出更多的复杂的可滚动的视图,比如水平方向的ListView,或者是Web上很流行的瀑布流式布局(Masonry)。只是大部分布局系统都没有提供,必须由开发者自己实现。
所以RecyclerView的“flexible”:什么都可以做,但什么都要自己做。
RecyclerView和ListView的主要区别
只要用Android提供的LieanerLayoutManager并配以VERTICAL模式,RecyclerView就可以完美达到ListView的基本效果。两者的设计结构也都是数据(Dataset)与视图(View)分离,然后通过适配器(Adapter)来连接的方式。
但RecyclerView相对ListView来说有以下几大提升:
- 没有OnItemClickListener
ListView从它的父类AdapterView直接继承了对子项目点击的响应,开发者可以定义自己的OnItemClickListner来接受点击事件。但这个设计也造成了一些问题,比如子项内部视图如果设置了OnClickListener,那么子项目视图本身并不会知道,从而可能会导致视图点击状态没有同步等问题。ReyclerView没有提供简便的响应子项目被点击的监听器,虽然它有一个OnItemTouchListener,但在这个接口方法中没有任何关于那个子项目被点击的信息,该接口只是帮助开发者截获触摸事件,对于如何处理,检测被触摸目标对象都留给了开发者去完成。
- 视图与布局分离
ListView做到了数据和视图的分离,RecyclerView在视图和布局之间再进一步分离,于是便有了LayoutManager。RecyclerView负责管理视图的重复利用,然后将布局方式全权交给了LayoutManager,通过配置或者切换LayoutManager就可以获得不同的布局效果。不像ListView被限制在垂直滚动布局。同时RecyclerView还提供了ItemDecoration,在已有的子视图基础上还可以添加额外的视图。比如做一条分割线,在ListView就需要额外占用一个ViewType来提供视图,现在则不需要在Adapter中加入这些与实际逻辑业务无关的辅助内容。
- 支持子项目层次的动画效果
ListView也可以支持子项目层次的动画效果,在Android Developers的DevBytes频道里有很多关于这方面的介绍,不过在看过其实现之后就会发现其解决方案是多么的丑陋而冗长。很多时候都是在计算和分析子视图的位置状态。RecyclerView则带来了非常简洁的ItemAnimator接口。当Adapter中的数据发生“增删改移”变化,通过调用Adapter相应的方法就可以激活动画的产生。当然开发者还需要自己实现具体的ItemAnimator对象来完成所需的动画效果,但是其清晰的结构和接口已比ListView有极大的进步。
RecyclerView的现状
上边提到RecyclerView的套件已经加入了Support Library v7,而且是以单独的库放入,所以只要在Android Studio项目的Gradle编译文件的dependencies下加入下边的这句就可以开始使用RecyclerView了:
compile 'com.android.support:recyclerview-v7:25.x.x'
不过看过库中提供的那些自带对象实现,体现基本操作流程,就会发现RecyclerView能做的看起来很多,但是已经做到的实在太少。
RecyclerView.Adaper
RecyclerView提供了一个抽象Adapter类,然后就没有了。没有任何可以直接使用的子类,像ListAdapter那样的ArrayAdapter、SimpleCursorAdapter现成的类都没有。一切都留给开发者自己去实现定义。
仔细想想这也很挺正常,相信应该很少在实际产品中有使用ArrayAdapter的,因为大部分列表都不会是简单的一行文字。对于CursorAdapter使用也往往会实现不同的继承类来提供子视图。再者RecyclerView的Adapter和ListAdapter在理念上还是一样的,所以想实现个RecyclerViewCursorAdapter,直接从CursorAdapter取材便可。
RecyclerView的Adapter相对ListAdapter在接口上有几处变化也值得注意。
首先其将getView()方法分拆成了createViewHolder()和bindViewHolder()两个。不过这个没有什么好紧张的,在CursorAdapter里就已经有见到过这个更加合理的设计。另外返回对象也从View变成了ViewHolder只需提一下。
最关键的注意点在于createViewHolder(ViewGroup parent, int viewType)第二参数虽然是整形,但是它并不是以往的当前子项的位置(position),而是调用getItemViewType()获得的的子项的类别。似乎在创建ViewHolder时,RecyclerView故意在隐藏子项的详细信息,希望开发者完全只依赖其类别来创建相应的View以及ViewHolder。
其次,RecyclerView的Adapter除了和ListAdapter一样有notifyDataSetChanged()方法外,还有一堆会触发动画效果的通知数据改变的方法:
- final void notifyItemChanged(int position); // 修改
- final void notifyItemInserted(int position); // 插入
- final void notifyItemMoved(int fromPosition, int toPosition); // 移动
- final void notifyItemRangeChanged(int positionStart, int itemCount); // 批量改变
- final void notifyItemRangeInserted(int positionStart, int itemCount); // 批量插入
- final void notifyItemRangeRemoved(int positionStart, int itemCount); // 批量删除
- final void notifyItemRemoved(int position); // 删除某个
调用这些方法就会激发ItemAnimator上对应的用于产生动画的方法。
RecyclerView.ViewHolder
在ListView的年代里,其实已经在使用ViewHolder,只是那时的方法看起来比较讨巧,要隐藏在View的Tag()里。现在RecyclerView强制使用ViewHolder,并且ViewHolder除了有对子视图的引用,还有诸如ItemViewType和Position这些信息。
mHolder.getItemViewType(); // 获取当前Holder类型
mHolder.getAdapterPosition(); // 获取当前的position(当有删除/新增item时,会时时更新),因此可替代通过Tag获取数据。
RecyclerView.LayoutManager
LayoutManager相对于ListView来说是一个新部分,通过继承该类来实现自定义的布局方式,而不像ListView只有固定的布局方式。Support库提供了两个现成的子类:LinearLayoutManager和StaggeredGridLayoutManager。前者可以获得和ListView一样的布局,还可以是水平方向的;后者则提供了形如GridView的布局。所以应用程序中的基本日常所以都可以被满足。
如果需要实现自定义的LayoutManager,就比较麻烦了,需要理解Recycle、Scrap、Dirty这些关于子项目视图状态的概念。
RecyclerView.ItemAnimator
通过继承实现ItemAnimator,然后创建对象设置到RecyclerView上就可以得到基于子项目的动画效果。不过如何正确合理地创建一个ItemAnimator子类,却没有详细的描述指南。
库中提供的唯一一个可用的子类DefaultItemAnimator,可以看出它的动画效果是简单的Alpha渐变。同时也会发现其实现是如此的复杂,有很多对于动画步骤的操作,还得注意动画在中途被打断的处理,在结束时也要重置视图状态以便重用。这也反过来说明ItemAnimator基本没有提供任何关于如何实现和管理动画的信息。另一方面因为DefaultItemAnimator的实现过于具体,因此它并不是合适作为自定义ItemAnimator的父类。
相信当RecyclerView越来越多的被应用到程序中时,更多关于这方面的合理设计会被提出来。目前在Github上也有不少参考了DefaultItemAnimator的实现方式,比如RecyclerViewItemAnimators、recyclerview-animators。
关于ItemAnimator的使用,有几点值得提醒的是:如果没有提供ItemAnimator,RecyclerView默认会创建一个DefaultItemAnimator用于动画,所以不需要显示地设置DefaultItemAnimator对象到RecyclerView上;添加(add)和删除(remove)是默认起效的,但是修改(change)的效果需要调用setSupportsChangeAnimations(boolean)来指定是否启用,其默认是没有修改的动画。
总体而言,RecyclerView的功能非常强大,其结构设计也十分开放,这也造成它的上手使用相对比较困难。随着越来越多的人开始尝试使用这个部件,也会有越来越深刻的理解和设计实现。另外,阅读RecyclerView的源码可以帮助对其设计思想的了解,在以后设计其它的复用视图时可以有更好的参照。
Android RecyclerView体验(一)- 简介的更多相关文章
- (转载) Android RecyclerView 使用完全解析 体验艺术般的控件
Android RecyclerView 使用完全解析 体验艺术般的控件 标签: Recyclerviewpager瀑布流 2015-04-16 09:07 721474人阅读 评论(458) 收藏 ...
- GitHub Android Librarys Top 100 简介
GitHub Android Librarys Top 100 简介 本项目主要对目前 GitHub 上排名前 100 的 Android 开源库进行简单的介绍, 至于排名完全是根据GitHub搜索J ...
- <Android开源库 ~ 1> GitHub Android Libraries Top 100 简介
转载自GitHub Android Libraries Top 100 简介 本项目主要对目前 GitHub 上排名前 100 的 Android 开源库进行简单的介绍, 至于排名完全是根据 GitH ...
- 极简的Android RecyclerView Adapter(使用DataBinding)
阅读本篇文章需要读者对Android Databinding和RecyclerView有一定的了解. 简介 我们知道,DataBinding的核心理念是数据驱动.数据驱动驱动的目标就是View,使用D ...
- 浅谈Android RecyclerView
Android RecyclerView 是Android5.0推出来的,导入support-v7包即可使用. 个人体验来说,RecyclerView绝对是一款功能强大的控件. 首先总结下Recycl ...
- [Android]RecyclerView的简单演示样例
去年google的IO上就展示了一个新的ListView.它就是RecyclerView. 下面是官方的说明,我英语能力有限,只是我大概这么理解:RecyclerView会比ListView更具有拓展 ...
- Android RecyclerView 实现支付宝首页效果
Android RecyclerView 实现支付宝首页效果 [TOC] 虽然我本人不喜欢支付宝的,但是这个网格本身其实还是不错的,项目更新中更改了一个布局为网格模式,类似支付宝.(估计是产品抄袭的= ...
- Android RecyclerView的基本使用
Android RecyclerView 在去年的Google I/O大会上就推出来了,以前经常使用的ListView 继承的是AbsListView,而RecyclerView则直接继承 ViewG ...
- Android RecyclerView单击、长按事件:基于OnItemTouchListener +GestureDetector标准实现(二),封装抽取成通用工具类
Android RecyclerView单击.长按事件:基于OnItemTouchListener +GestureDetector标准实现(二),封装抽取成通用工具类 我写的附录文章2,介绍了 ...
随机推荐
- 【iOS】iOS它Container View获得ViewController
近期使用Container View来在主View Controller建立自己的子Controller,但是遇到问题.不知道怎样用代码获取Controller View附带的View Control ...
- NGUI ScrollView动态加入和删除对象。
动态加入,基本思想是: 1.先把要加入的元素在编辑器中编辑好,制作成一个prefab. 2.在代码中,动态的生成一个新的对象增加到Grid对象的子对象中.这里利用到了Resources对象,这个对象的 ...
- cocos2d-x-lua基础系列教程三(lua面向对象)
lua 类 Lua 事实上不是面向对象语言 我们能够用table 模拟仿照面向对象编程 lua 中的this 类似的是self table 也具有生命周期 2,使用table 创建类 projed ...
- Android4.3引入的UiAutomation新框架官方简介
译者序:Google在Android 4.3发布时提供了一套新的UiAutomation框架来支持用户界面自动化测试,该框架通过运用已有的Accessibility APIs来模拟用户跟设备用户界面的 ...
- C++ - 模板类模板成员函数(member function template)隐式处理(implicit)变化
模板类模板成员函数(member function template)隐式处理(implicit)变化 本文地址: http://blog.csdn.net/caroline_wendy/articl ...
- jquery+html三级联动下拉框及详情页面加载时的select初始化问题
html写的三个下拉框,如下: <select name="ddlQYWZYJ" id="ddl_QYWZYJ" class="fieldsel ...
- HBuilder HTML 自定义代码块
=begin 本文档是HTML代码块的编辑文件.注意不要把其他语言的设置放到html里来. HBuilder可使用ruby脚本来编辑代码块和增强操作命令. 1.编辑代码块 如果要新增一个代码块,复制如 ...
- CSS学习笔记:利用border绘制三角形
在前端的笔试.面试过程中,经常会出现一些不规则图形的CSS设置,基本上多是矩形外加一个三角形.利用CSS属性可以实现三角形的生成,主要利用上下左右的边距的折叠. 1.第一种图形: .box { wid ...
- 阿里云1218动态css3代码
See the Pen jEWpWm by kujian (@kujian) on CodePen. .room-nav { /* -webkit-animation:roomNavTranslate ...
- wp7学习笔记
1.xap:最终是压缩包:最终部署有系统控制,防止流亡软件:放到固有位置productid;有的文件放在.dll中或直接放入目录下:控制有生成操作:content,内容,content效率更高不用从. ...