欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android中的RecyclerView新组件初步上手指南

程序员文章站 2024-03-03 17:28:04
介绍 recyclerview是support-v7包中的新组件,是一个强大的滑动组件,与经典的listview相比,同样拥有item回收复用的功能,但是直接把viewh...

介绍

recyclerview是support-v7包中的新组件,是一个强大的滑动组件,与经典的listview相比,同样拥有item回收复用的功能,但是直接把viewholder的实现封装起来,用户只要实现自己的viewholder就可以了,该组件会自动帮你回收复用每一个item。
它不但变得更精简,也变得更加容易使用,而且更容易组合设计出自己需要的滑动布局。

recyclerview与listview原理是类似的:都是仅仅维护少量的view并且可以展示大量的数据集。recyclerview用以下两种方式简化了数据的展示和处理:
(1)使用layoutmanager来确定每一个item的排列方式。
(2)为增加和删除项目提供默认的动画效果。
你也可以定义你自己的layoutmanager和添加删除动画,recyclerview项目结构如下:

Android中的RecyclerView新组件初步上手指南

(1)adapter:使用recyclerview之前,你需要一个继承自recyclerview.adapter的适配器,作用是将数据与每一个item的界面进行绑定。
(2)layoutmanager:用来确定每一个item如何进行排列摆放,何时展示和隐藏。回收或重用一个view的时候,layoutmanager会向适配器请求新的数据来替换旧的数据,这种机制避免了创建过多的view和频繁的调用findviewbyid方法(与listview原理类似)。
目前sdk中提供了三种自带的layoutmanager:
(1)linearlayoutmanager
(2)gridlayoutmanager
(3)staggeredgridlayoutmanager

使用它的理由:
简单说,它是listview的进化,为了当你需要动态展示一组数据的时候就会需要它。
当然,如果只是动态展示数据,listview也可以做到,用它替代listview的原因有几个:
(1)简介中提到的它封装了viewholder的回收复用。
(2)recyclerview使用布局管理器管理子view的位置(目前尚只提供了linearlayoutmanager),也就是说你再不用拘泥于listview的线性展示方式,如果之后提供其他custom layoutmanager的支持,你能够使用复杂的布局来展示一个动态组件。
(3)自带了itemanimation,可以设置加载和移除时的动画,方便做出各种动态浏览的效果。

官方样例:
xml:

<!-- a recyclerview with some commonly used attributes --> 
<android.support.v7.widget.recyclerview 
  android:id="@+id/my_recycler_view" 
  android:scrollbars="vertical" 
  android:layout_width="match_parent" 
  android:layout_height="match_parent"/> 

main code:

public class myactivity extends activity { 
  private recyclerview mrecyclerview; 
  private recyclerview.adapter madapter; 
  private recyclerview.layoutmanager mlayoutmanager; 
 
  @override 
  protected void oncreate(bundle savedinstancestate) { 
    super.oncreate(savedinstancestate); 
    setcontentview(r.layout.my_activity); 
    mrecyclerview = (recyclerview) findviewbyid(r.id.my_recycler_view); 
 
    // improve performance if you know that changes in content 
    // do not change the size of the recyclerview 
    mrecyclerview.sethasfixedsize(true); 
 
    // use a linear layout manager 
    mlayoutmanager = new linearlayoutmanager(this); 
    mrecyclerview.setlayoutmanager(mlayoutmanager); 
 
    // specify an adapter (see also next example) 
    madapter = new myadapter(mydataset); 
    mrecyclerview.setadapter(madapter); 
  } 
  ... 
} 

adapter code:

public class myadapter extends recyclerview.adapter<myadapter.viewholder> { 
  private string[] mdataset; 
 
  // provide a reference to the type of views that you are using 
  // (custom viewholder) 
  public static class viewholder extends recyclerview.viewholder { 
    public textview mtextview; 
    public viewholder(textview v) { 
      super(v); 
      mtextview = v; 
    } 
  } 
 
  // provide a suitable constructor (depends on the kind of dataset) 
  public myadapter(string[] mydataset) { 
    mdataset = mydataset; 
  } 
 
  // create new views (invoked by the layout manager) 
  @override 
  public myadapter.viewholder oncreateviewholder(viewgroup parent, 
                          int viewtype) { 
    // create a new view 
    view v = layoutinflater.from(parent.getcontext()) 
                .inflate(r.layout.my_text_view, parent, false); 
    // set the view's size, margins, paddings and layout parameters 
    ... 
    viewholder vh = new viewholder(v); 
    return vh; 
  } 
 
  // replace the contents of a view (invoked by the layout manager) 
  @override 
  public void onbindviewholder(viewholder holder, int position) { 
    // - get element from your dataset at this position 
    // - replace the contents of the view with that element 
    holder.mtextview.settext(mdataset[position]); 
 
  } 
 
  // return the size of your dataset (invoked by the layout manager) 
  @override 
  public int getitemcount() { 
    return mdataset.length; 
  } 
} 

替用gallery:
笔者使用recyclerview的原因其实并不是为了使用一个新颖的组件去实现华丽的功能,就在前一天我还在到处寻找一个可以替代deprecated组件gallery的组件。其实在gallery弃用之后,recyclerview出来之前,viewpager和扩展scrollview是*上推荐的实现gallery的两种解决办法,但是都有一定的问题,scrollview要实现gallery的改动太大,viewpager替用的滑动体验和原来的gallery相去甚远。

顺着官方demo,我替换掉原来的viewpager类,使用recylcerview,改进有以下几点:

(1)使用过viewpager动画的应该知道(有经典的viewpager动画第三方扩展jazzyviewpager),这些动画是为了提供给每个item占据全屏,或占据几乎全屏这种情况设计的。也就是说,如果你简单地将viewpager的每页显示数设置为你需要的值,之后设置的动画很可能并不是你需要的效果(因此之前我在嵌套时去掉了viewpager的动画,稍微有点失望)。
(2)滑动速度加快,因为viewpager并不是viewspager。。。一次长距离的滑动可能只造成1~2张图片的滚动,一点也不像gallery,这是我用recylcerview替代它的主要原因。

基于原来的代码,我构建了myrecyclergallery,保留了原来的触摸事件,现在滑动起来舒服多了:

Android中的RecyclerView新组件初步上手指南

你可以看到滑动时还有滚动条。事件机制和原来一样,recyclerview的关键代码没有变化,所以就不放出源码了。