RecyclerView到底强大在哪里?

AnaOakley 8年前
   <p style="text-align:center"><img src="https://simg.open-open.com/show/8bb70596e84f56cd713dfcf99f9b0b48.jpg"></p>    <p style="text-align:center">魅力安卓</p>    <p>Hello,大家好!通过上次总结,我们回顾了一下ListView的用法,也知道了ListView的缺陷,比如:性能较差,需要采取手段提高性能;扩展性较差等。同时也知道了一个更为强大的滚动控件RecyclerView将要代替ListView的趋势。那么,RecyclerView是怎样实现的,究竟又强大在哪里?</p>    <p>今天,我们就一起来学习总结下吧~</p>    <p>先上图(这里我们同样采用神奇宝贝素材):</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/a7347d37176b045f4ce345c7c2d33862.gif"></p>    <p>单凭横向滚动这一点,就是ListView所做不到的。</p>    <p><strong>1. 实现过程</strong></p>    <p>不同于ListView,RecyclerView属于新增控件,在使用之前需要先在build.gradle中引用依赖库:support:recyclerview -v7 。</p>    <p>采取和ListView同样的分析思路,要实现一个RecyclerView的demo,主要分两步:</p>    <p>首先是布局的设计,主布局(activity_main)中,放入一个RecyclerView控件。再建一个子布局(pokemon_item),子布局中还是包含一个ImageView和一个TextView控件,分别用来显示图片和文字素材。</p>    <p>布局代码如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/0062e51720026932bc55914fb838108d.png"></p>    <p>然后是逻辑代码的编写,先看MainActivity:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/00c4c4a8953b7b7f60c30fd1779b10a8.png"></p>    <p>我们可以看到,代码中和ListView的MainActivity中代码相同的,都是先通过fbc获取到RecyclerView控件,new一个适配器adapter,调用setAdapter方法。</p>    <p>但是除此之外,我们可以看到红框中标记出来的两行代码,这是干什么用的呢?我们稍后回过头来再看,你就会明白了。</p>    <p>除了MainActivity,我们知道应该还有两个类,一个是我们自己定义的适配器MyAdapter,另一个是实体类,用于适配器泛型的指向,初始化数据。这里我们简化一下,除去实体类,只留下MyAdapter类,至于数据,我们采用直接赋值的简便方法。</p>    <p>MyAdapter.java代码如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/0aa8d831264b25b7a995904df9ebb792.gif"></p>    <p>梳理一下,代码还是比较清晰的。首先我们定义MyAdapter类,继承自Recycler.Adapter并将泛型指向MyAdapter.ViewHolder(MyAdapter中我们自己定义的一个内部类),接下来就是定义的ViewHoler内部类,内部类中又包括其成员变量和构造函数,以及一个初始化数据时用到的setData的方法;跳出内部类,就是整个MyAdapter类的构造函数,重写的三个父类方法:onCreateViewHolder(用来加载子布局,并返回ViewHolder实例)、onBindViewHolder(调用setData方法,在子项滚进屏幕时,对RecyclerView子项数据进行赋值)、getItemCount(获取RecyclerView子项的个数)。</p>    <p>这样,在Myadapter中我们就完成了,数据初始化和适配器的内容。这是我们将思路返回到MainActivity红框标注的两行代码处。我们可以理解,这应该是创建了一个LinearLayoutManager对象,通过setLayoutManager方法来指定了RecyclerView的布局方式。</p>    <p>此时运行代码,即可展现与ListView相同的效果:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/0588f57585569874233221362a40fd91.gif"></p>    <p><strong>2. 多种布局样式</strong></p>    <p>通过上面的分心,可利用RecyclerView实现ListView上下滑动列表的效果。那么,横向滚动的列表效果是怎样实现的呢?得益于RecyclerView强大的扩展性,实现起来并不难,甚至仅通过几行代码即可达到我们想要的效果!</p>    <p>其中奥义就在于MainActivity中我们用红框标注出来的那两行代码:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/000c75605a89bb2d8a0ce8437eb058ce.png"></p>    <p>这里调用linearLayoutManger的setOrientation()方法,参数为HORIZONTAL(横向),即可实现横向效果!截图如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/e5572b3d62a4585139f40580ade02268.gif"></p>    <p>聪明的你,应该发现了,这个LinearLayoutManger表示线性布局,可以通过setOrientation()方法设置布局的排列方向,默认为纵向。其实除此之外,RecyclerView还有GridLayoutManager(网格布局)和StaggerGridLayoutManager(瀑布流布局)的内置布排列方式。实现起来也很简单,举一反三,我相信你已经猜到,只需根据你的需要将LinearLayoutManager替换成GridLayoutManager或StaggerGridLayoutManager,传入对应的参数,将其通过setLayoutManager赋给我们的RecyclerView即可。</p>    <p>横向网格布局截图如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/02f333d47e127623f72a9c4ed0096598.gif"></p>    <p>当子项高度不一致时,瀑布流效果才更加好看,回头我们会单独在瀑布流相关的几个小demo里面实现。</p>    <p><strong>3. 强大之处在哪里?</strong></p>    <p>通过上面的简单分析,我们大概能总结出RecyclerView几个优缺点:</p>    <p>1.相对于ListView而言,效率性能等的优化提升,MyAdapter中ViewHolder的编写更加规范化,不在需要调用setTag等操作进行item复用;</p>    <p>2.更强的扩展性,更方便使用的多样化布局效果。现在RecyclerView官方能够支持的就包括了线性布局、网格布局、瀑布流布局的方式,其中还可以控制纵向还是横向效果。这就意味着,你不必再去找横向ListView、横向GirdView、瀑布流效果等第三方开源控件,使用RecyclerView即可满足你的要求。</p>    <p>3.另外在数据刷新、动画效果等多方面,都有更多的优势和玩法,看看还有点小激动呢,知识真是丰富呢,有种求知若渴的感觉^_^</p>    <p><strong>4. 关于点击事件</strong></p>    <p>对了,关于RecyclerView的点击事件,并不像ListView那样通过setOnItemClickListener()监听即可实现。而是需要我们对子项的每个View注册点击事件,实现相对可能较复杂一点,但是说实话,在你使用的时候你就会发现其隐藏的优势:ListView的点击事件是设置在子项上面的,并不能给子项里面某一个明确的控件设置点击事件,就比如我们的子项包含一个ImageView和一个TextView,并不能设置单独的点击事件;而RecyclerView设置的点击事件在具体的View中注册,这样稍微复杂点,但指向性更为明确。</p>    <p>RecyclerView的相关应用及扩展,还是很广很迷人的。希望这篇总结能够起到抛砖引玉的效果,望各位在日后的学习和应用中,不断总结完善,体会RecyclerView更加深层次的奥妙~</p>    <p> </p>    <p> </p>    <p>来自:http://www.jianshu.com/p/7bd434d983e9</p>    <p> </p>