RecyclerView技术栈

概述

随着2014年Google IO的召开,Android L Preview版随之公布,对于开荒着来说,带来了品质上的精雕细琢,而对于客户来讲,获得了体验上的晋级。小编想,无论是开辟者依然使用者,一定都万分喜欢此番的版本跟新。

况兼,本次也推动了多个斩新的View控件:RecyclerViewCardView。那篇文章将重点介绍RecyclerView,它有那二个之中类和接口。接下来,作者将介绍它们的功用,已经怎么着行使。

自然,在此后面,我要证明的是:RecyclerView 是Support Library的生机勃勃部分。所以只须要在app/build.gradle中增添以下正视,便能立即选择:

dependencies {
    compile 'com.android.support:recyclerview-v7:23.2.0'
}

然后点击“Sync Project with Gradle files”,让IDE去下载适当的资源文件。

移动端:iOS

缘何取名称为RecyclerView?

先让我们来探视谷歌在L Preview中是怎么定义RecyclerView的:

A flexible view for providing a limited window into a large data set.
(能够在有限的窗口中显得大数量集结的灵巧视图。)

因而大家能够知情为,RecyclerView一个恰到好处的行使境况是:由于尺寸限制,客户的装置不能够壹次性表现全数规行矩步,客商供给上下滚动以查看更加的多条目款项。滚出可知区域的条文将被回笼,并在下贰个条文可以知道的时候被复用。

笔者们能够从下图中获得越来越直观的讲授:

左侧包车型大巴图是多少初阶化后的示范,当发展滚动视图的时候,当条款不可以知道之后将被回收。右图中肉桂色区域内的两条不可知条款,将被放置缓存队列中以便新的条规可以知道时开展复用。

对于收缩内部存款和储蓄器开支和CPU的盘算,缓存条目款项是二个可怜平价的章程,因为那意味着我们无需每回都创制新的条款,进而减少内存费用和CPU的乘除,并且还是可以行得通缩小显示器的卡顿,有限扶助滑动的顺滑和16ms法规。

见到这里,你可能不禁止开会问:并从未什么样新东西啊,那和ListView有怎样界别呀?大家早已选用ListView十分短大器晚成段时间了哟,它风度翩翩律能够成功呀。可是,视图回笼自家并非如何新鲜事。不过回看此前我们写的ListView,无论从它的的习性表现初阶,照旧语法的书写,以致数据的绑定都未免略显丰腴。那么今后,我们将再也不会出现上述症状,因为谷歌(Google)提供了叁个更加好,更加灵敏的控件——RecyclerView

OK,从今日始发,让我们一步一步,开首询问它。

前端:

结构

纵然您想利用RecyclerView,要求做以下操作:

  • RecyclerView.Adapter - 管理数量集合併担当绑定视图

  • ViewHolder - 持有全数的用于绑定数据也许需求操作的View

  • LayoutManager - 担负安排视图等唇揭齿寒操作

  • ItemDecoration - 担当绘制Item周围的分水线

  • ItemAnimator - 为Item的相似操作增多动画功效,如,增加和删除条目款项等

咱俩得以从下图更加直观的领会到RecyclerView的骨干组织:

不问可以见到,想要在ListView中落实条指标增加和删除动画是风流洒脱件十分不方便的事体,然而RecyclerView为大家提供了很好的便利。何况RecyclerView增强了ViewHolder设计格局,那在现阶段所选择的ListView中是未有有的。

后端:Java EE

与传统ListView比较

RecyclerView与老生机勃勃辈ListView的不相同点,首要在于以下多少个特色:

  • Adapter中的ViewHolder模式 - 对于ListView来说,通过创建ViewHolder来提高质量并非必得的。因为ListView并未严俊的ViewHolder设计格局。不过在行使RecyclerView的时候,Adapter总得兑现起码三个ViewHolder,必需根据ViewHolder设计形式。

  • 定制Item条目 - ListView唯其如此促成垂直线性排列的列表视图,与之不一致的是,RecyclerView可以通过安装RecyclerView.LayoutManager来定制不一致风格的视图,举例水平滚动列表或然不许则的瀑布流列表。

  • Item动画 - 在ListView中从未提供任何格局大概接口,方便开辟者达成Item的增加和删除动画。相反地,可以经过设置RecyclerViewRecyclerView.ItemAnimator来为条约扩大动画效果。

  • 安装数据源 - 在LisView中针对分化数量封装了各种类型的Adapter,比如用来管理数组的ArrayAdapter和用来显示Database结果的CursorAdapter。相反地,在RecyclerView中必须自定义完成RecyclerView.Adapter并为其提供数据集结。

  • 设置条款分界线 - 在ListView中得以经过设置android:divider质量来为八个Item间设置分水线。假诺想为RecyclerView加多此作用,则必需选取RecyclerView.ItemDecoration,这种完成格局不止越来越灵活,并且样式也愈发丰硕。

  • 安装点击事件 - 在ListView中存在AdapterView.OnItemClickListener接口,用来绑定条指标点击事件。不过,特别不满的是在RecyclerView中,并从未提供这么的接口,可是,提供了此外八个接口RcyclerView.OnItemTouchListener,用来响应条约标触摸事件。

数据库:MySQL

RecyclerView组件

RecyclerView.Adapter

确切的说,Adapter扮演着七个角色。风度翩翩是,依照区别ViewType创设与之对应的的Item-Layout,二是,访谈数据集合併将数据绑定到科学的View上。那就必要大家重写以下多少个函数:

  • public VH onCreateViewHolder(ViewGroup parent, int viewType) 成立Item视图,并回到相应的ViewHolder

  • public void onBindViewHolder(VH holder, int position) 绑定数据到准确的Item视图上。

除此以外大家还亟需重写另二个方法,像ListView-Adapter那样,同样地告知RecyclerView-Adapter列表Items的总额:

  • public int getItemCount() 再次来到该艾达pter所持有的Itme数量

RecyclerView.ViewHolder

ViewHolder的主导用法是用来寄存View对象。Android团队很早从前就引入应用“ViewHolder设计情势”,但骨子里他们并不曾把这种概念强加给开荒者,而且也从未必要开采者在Adapter中必得选择ViewHolder pattern。那么未来对于这种新颖的RecyclerView.Adapter,大家亟须兑现并选择它。

别的值得风流倜傥提的是,能够透过打字与印刷ViewHolder.toString来赢得越来越多立见功用新闻:

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("ViewHolder{" +
                Integer.toHexString(hashCode()) + " position=" + mPosition + " id=" + mItemId +
                ", oldPos=" + mOldPosition + ", pLpos:" + mPreLayoutPosition);
        if (isScrap()) sb.append(" scrap");
        if (isInvalid()) sb.append(" invalid");
        if (!isBound()) sb.append(" unbound");
        if (needsUpdate()) sb.append(" update");
        if (isRemoved()) sb.append(" removed");
        if (shouldIgnore()) sb.append(" ignored");
        if (isChanged()) sb.append(" changed");
        if (isTmpDetached()) sb.append(" tmpDetached");
        if (!isRecyclable()) sb.append(" not recyclable(" + mIsRecyclableCount + ")");
        if (isAdapterPositionUnknown()) sb.append("undefined adapter position");
        if (itemView.getParent() == null) sb.append(" no parent");
        sb.append("}");
        return sb.toString();
    }

所以,贰个大旨的RecyclerView.Adapter如下:

public class SimplerItemAdapter extends RecyclerView.Adapter<SimplerItemAdapter.SimpleItemViewHolder> {

  private List<String> items;

  public SimplerItemAdapter(@NonNull List<String> dateItems) {
    this.items = (dateItems != null ? dateItems : new ArrayList<String>());
  }

  @Override public SimpleItemViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
    View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
    return new SimpleItemViewHolder(itemView);
  }

  @Override public void onBindViewHolder(SimpleItemViewHolder viewHolder, int position) {
    viewHolder.textView.setText(items.get(position));
  }

  @Override public int getItemCount() {
    return (this.items != null) ? this.items.size() : 0;
  }

  protected final static class SimpleItemViewHolder extends RecyclerView.ViewHolder {
    protected TextView textView;

    public SimpleItemViewHolder(View itemView) {
      super(itemView);
      this.textView = (TextView) itemView.findViewById(R.id.text);
    }
  }
}

RecyclerView.LayoutManager

LayoutManager的任务是摆放Item的岗位,何况担当控制曾几何时回笼和起用Item。

总得为RecyclerView钦命LayoutManager,不然会自可是然以下万分:

 AndroidRuntime java.lang.NullPointerException: Attempt to invoke virtual method ‘void android.support.v7.widget.RecyclerView$LayoutManager.onMeasure(android.support.v7.widget.RecyclerView$Recycler, android.support.v7.widget.RecyclerView$State, int, int)’ on a null object reference
  • LinearLayoutManager 水平依旧垂直的Item视图。

  • GridLayoutManager 网格Item视图。

  • StaggeredGridLayoutManager 交错的网格Item视图。

自然还应该有局地很实用的API:

  • findFirstVisibleItemPosition() 重返当前首先个可以知道Item的position
  • findFirstCompletelyVisibleItemPosition() 重回当前第二个精光可以知道Item的position
  • findLastVisibleItemPosition() 重回当前最终三个可以见到Item的position
  • findLastCompletelyVisibleItemPosition() 再次来到当前最终四个截然可知Item的position

LayoutManager当前有且只有一个大而无当函数:

public LayoutParams generateDefaultLayoutParams()

此外值得注意的是,自定义LayoutManager还相应达成以下格局:

   /**
     * Scroll to the specified adapter position.
     *
     * Actual position of the item on the screen depends on the LayoutManager implementation.
     * @param position Scroll to this adapter position.
     */
    public void scrollToPosition(int position) {
        if (DEBUG) {
            Log.e(TAG, "You MUST implement scrollToPosition. It will soon become abstract");
        }
    }

RecyclerView.ItemDecoration

经过设置recyclerView.addItemDecoration(new DividerDecoration(this));来改动Item之间的偏移量可能对Item进行李装运饰。

本来,你也得以对RecyclerView设置多少个ItemDecoration,列表显示的时候会遍历全数的ItemDecoration并调用里面包车型地铁绘图方法,对Item进行装点。

RecyclerView.ItemDecoration是贰个抽象类,能够通过重写以下三个艺术,来兑现Item之间的偏移量可能点缀效果:

  • public void onDraw(Canvas c, RecyclerView parent) 装饰的绘图在Item条目款项绘制早先调用,所以那有比十分大概率被Item的剧情所遮挡

  • public void onDrawOver(Canvas c, RecyclerView parent) 装饰的绘图在Item条目款项绘制之后调用,由此装饰将浮于Item之上

  • public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) 与padding或margin类似,LayoutManager在衡量阶段会调用该措施,总计出每叁个Item的没错尺寸并设置偏移量。

RecyclerView技术栈。RecyclerView.ItemAnimator

ItemAnimator能够协理Item实现独立的动画。

ItemAnimator作触发于以下两种事件:

  1. 某条数据被插入到数量群集中
  2. 从数量集结中移除某条数据
  3. 改造数据集合中的某条数据

有幸的是,在Android中默许达成了三个DefaultItemAnimator,我们能够透过以下代码为Item扩展动画效果:

recyclerView.setItemAnimator(new DefaultItemAnimator());

在事先的版本中,那时候据群集产生转移时,大家由此调用.notifyDataSetChanged(),来刷新列表,因为这么做会触发列表的重绘,所以并不会出现任何动画效果,因而需求调用一些以notifyItem*()用作前缀的非正规形式,比方:

  • public final void notifyItemInserted(int position) 向钦赐地点插入Item

  • public final void notifyItemRemoved(int position) 移除钦点地方Item

  • public final void notifyItemChanged(int position) 更新钦命地方Item

Listeners

很遗憾,RecyclerView并未像ListView那样提供以下五个Item的点击监听事件

  • public void setOnItemClickListener(@Nullable OnItemClickListener listener) Item点击事件监听

  • public void setOnItemLongClickListener(OnItemLongClickListener listener) Item长按事件监听

不过存在此么贰个触摸事件的监听RecyclerView.OnItemTouchListener纵然变得更加灵活,不过相应的代码量和书写难度却有了自然的滋长,最少对作者是如此的。

至此,全体与本小说相关的代码都能够从Github上获得到,别的那些库房中还大概有大器晚成份本人精心制作的PPT,可供参考。

运维:Linux

参照他事他说加以考察资料:

Codepath

  • Codepath Website

A First Glance at Android’s RecyclerView

  • WolframRittmeyer

本文由明仕msyz手机版发布于情感专区-情绪智力,转载请注明出处:RecyclerView技术栈

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。