Android:RecyclerView的使用(附菜单创建)

在android应用中经常要看到一些列表式的东西,比如QQ、微信的消息列表,还有网格式及瀑布式的格局,这些东西让我们看起来相当的有规则,看起来算是比较美观的,今天我主要介绍RecyclerView的使用。

RecyclerView这个控件引自v7包,在使用前切记要导包。

RecyclerView说白了就是ListView的升级版,不过它只关注回收和复用,在ListView中有时候根据需要我们会自定义适配器adapter,自定义适配器就一定要复写getView()方法。这时就要暴露一个问题,单纯在这里面给那些控件设置属性就可以了吗?当然你可以这么做,但是你要考虑一个问题,如果你的信息量非常大,比如现在你的ListView中有1w、10w甚至更多的item你觉得你的应用会奔溃吗?— —我觉得应该是会的,并且是死于内存溢出。所以针对性能上的问题,我们通常会设置一个ViewHolder辅助类来作为item的缓存,这样就基本实现了内存的复用。

RecyclerView与之不同,官方给它配置了一个专用的适配器RecyclerView.Adapter。该适配器的使用与之前我们自定义的略有区别,为了让ViewHolder得到更多的重视,以及性能方面的考虑,官方把这个适配器和ViewHolder绑定在一起。这次我们不再去创建getView(),而是将其功能一分为二,分别是onCreateViewHolder()和onBindViewHolder(),看名字就知道,前者是创建ViewHolder,后者是绑定,也就是设置一个ViewHolder给设置属性。

废话不多说,接下来上干货:

源码地址:https://github.com/QianLiStudent/MyStudyDemoRepository

1. 首先是在布局文件设置一下RecyclerView这个控件,此处不赘述。

2. (前面说RecyclerView是ListView的升级版)定义好数据源(通常用集合,可以动态添加、删除元素等)、适配器、初始化RecyclerView对象、给RecyclerView设置适配器。


数据源的话大家就在创建适配器之前自己设置吧。

3. RecyclerView是多变的,它可以变换成很多种类的格局,常见的有列表式、网格式、瀑布式等。接下来我们要做的就是设置布局管理器recyclerView.setLayoutManager(),其参数针对上面提到的有列表式:LinearLayoutManager(参数查看api文档),网格式:GridLayoutManager(参数查看api文档),瀑布式:StaggeredGridLayoutManager(参数查看api文档)。

4. 第3步走完就可以显示了,这里是展示的是列表式,那么怎么让RecyclerView动态变换格局呢?看这里:

这里我设置一个菜单,故这里采用switch做匹配,一开始我们设置布局管理器采用setLayoutManager(),变换其实就是setLayoutManager(格局1)→setLayoutManager(格局2),参数是布局管理器,详情查看api。

5. 这样做出来之后你就可以运行了,但是总是觉得哪里不对劲???没错,他变成一整块面板了,对某些人来说(至少对我来说)很丑对吧?这好办,给它设置分隔线不就得了

由于官方并没有提供分隔线相关的java类,故我们需要自己去写一个或者采用其他作者所写的,我们也可以考虑在res/values/styles.xml中自己定义,这里我觉得没什么必要,当然也是根据需要啦。不过啊,我觉得专门去做一个分隔线不管采用上面哪种方式都挺麻烦的,这里有一个十分方便的办法。首先你要知道,我们设置分隔线是给谁设置的?——没错,就是给item,为了让item与item之间有明显的边界,我们可以在设置布局文件的时候给最外层的控件(即XXXLayout)设置一个android:layout_margin="xxx",这里我把margin设置为全方位的外边距,显得四周都有分隔,当然可以根据自己需要来设定,这样我们也能做出分割线的效果,个人觉得还是挺美观的,而且使用也方便。

6. 上面提到RecyclerView是ListView的升级版,自然它也和ListView一样是用来做内容容器的。我们不能要求用户只使用我们提供的固定数据,因此这里我们需要在adapter中写添加和删除的方法。


这里我为了测试就直接把保存的数据写成“Insert here”,根据需要这里应该在add后面的参数增加一个要保存的数据,position参数表示你要添加的数据的位置,合法的位置是:     0~集合Object.size()(tip:这个合法位置是针对add方法的)。我们在添加集合元素前面设置position是为了让集合中的数据顺序和控件展示顺序一致。加进去之后我们要提醒adapter数据发生变化了,让它做数据更新,这时就要调用notifyItemInserted(position),对指定位置做局部刷新。注意,这里我们不能使用notifyDataSetChanged(),这么做会把所有的数据都刷新一遍,是会降低性能的。接下来是delete,其后面的参数也是指定要删除item的位置,合法的位置是:0~集合Object.size()— 1(tip:这个合法位置是针对delete方法的),然后调用notifyItemRemoved(position),这里也是局部刷新。在使用的时候有时候代码提示会出现notifyItemChanged(position),这个是改变,即如果你在add的时候使用这个方法进行刷新,那么在你指定位置的item会被你新添加进来的item给取代掉,也就是说集合数量增加了,但是你在适配器这里数量没有增加,只是把position的item给替换掉了内容。慎用  慎用  慎用~~

7. RecyclerView这个控件啊,官方做的还是很贴心的,他给我们提供了RecyclerView中的默认动画类DefaultItemAnimator,使用如下:

使用方式超级简单,至于动画类是怎么做的有兴趣的可以去研究,但是单纯使用的话就上面一句话就够了,是不是很贴心 ~ ,个人觉得这个效果还是很棒的,当然有很多大神自己写了动画,大家也可以去参考别人的或者考到本地引用,根据需要吧。

8. 展示出来的信息本来就是给别人看的,显示在表面的毕竟内容有限,我们通常会在点击或者其他事件触发后进入到更深层看到item内部的具体内容,就点击而言,我们就要给item设置点击事件来监听和做事件处理,对吧。但是官方并没有给我们提供任何的类、接口啥的,故我们需要自己定义接口,这里这里:

这里定义的回调方法是为了让适配器监听item点击系列事件,当该回调方法被调用的时候回传过来一个实例对象,下面通过判断是否为空来判断是否有调用该回调方法。也就是如果你不设置监听器,是没有办法触发监听事件的。

此方法在onBindViewHolder中调用,在adapter中我们会多次使用到holder.itemView。这个其实是我们定义了ViewHolder类的子类,从父类那里继承过来的属性itemView,holder在这里可以理解为一条本缓冲过得item所代表的对象,holder.itemView才是一条真正的item,然后在Activity中的adapter给它设置监听器就可以做监听了。有读者会想到为什么这里监听到事件后不直接在这里做处理呢?干嘛还回调到别的地方去?是的,你的想法是没错的,但是我们要考虑一个问题,你在这边貌似什么都做不了,什么Toast,Dialog,Intent啥都做不了,就像有一个工作室B了解(理解为代码中的监听)到工作室A有一个项目要找人外包,但是由于某种原因自己做不了,故把这个机会推荐给工作室C让他们去做。

这里提一下瀑布流高度是怎么实现的。

瀑布流的格局我们看起来是高度不一的对吧。那其实就是一个随机数生成的高度,我们定义一个随机数,然后在onBindViewHolder中给设置一下高度就行了,代码如下:


这个随机数集合我们可以放在构造方法中实现
这里参数命名都很明确,就不再赘述

AS是默认没有给菜单的初始化和事件监听的方法了,因此我们需要自己去创建:onCreateOptionMenu()和onOptionItemSelected(),在这之前我们要在res下创建一个Menu的folder:右键res - New - Android Resources Directory - Resources Type - menu,建完folder之后在里面创建一个Menu Resources File,然后xml里面的内容就是一个一个的item

android:showAsAction=“ifRoom”设置在标题栏处,若为“never”则作为隐藏列表菜单项

然后是先前提到的两个方法:


中间的内容根据需要自己补充吧。

以上是关于RecyclerView基本使用的整体流程及menu的创建和引用。

本文的学习内容学自鸿洋大神在慕课网的视频:

https://www.imooc.com/learn/424

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 【Android 控件 RecyclerView】 概述 RecyclerView是什么 从Android 5.0...
    Rtia阅读 307,320评论 27 439
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,400评论 25 707
  • (我的公众号:章乔) 期待你来 临近期末了,本来应该一门心思好好复习的,我却还是忍不住 “诱惑”,在不充裕的复习时...
    章乔阅读 1,696评论 0 1
  • 从小学开始我就是个小胖子,长大点就变成一个不折不扣的大胖子,小时候爸爸总是宠爱的说我胖胖的可爱。我也一直活在这种...
    奔着幸福跑的猪阅读 568评论 0 0
  • 话说这次老公带狗回来又是先斩后奏,第一次我暴跳如雷,立马送人;第二次我愤怒至极,放到妈家养了几天也送人了……这...
    焱妃夕妍雪阅读 272评论 0 0