深入RecyclerView-为什么要使用ItemDecoration

Part 1:不要用view做分割线

首先,什么是ItemDecoration?来看看官网是如何解释的。

ItemDecoration允许从adapter的数据集合中为特定的item视图添加特性的绘制以及布局间隔。它可以用来实现item之间的分割线,高亮,分组边界等。

我们不能简单的把ItemDecoration看成一个名字响亮的分割线。它比divider要多很多内容。一个divider只能绘制在item之间,但是ItemDecoration可以绘制在item的四边。ItemDecoration为decoration的测量和绘制提供了全方位的控制。一个decoration可以是一条分割线,也可以仅仅是一个间隔(inset)。

但不幸的是,绝大多数android开发者都没有使用item decoration。在这个分为三部分的系列文章中,我们将了解ItemDecoration的强大之处。

第一部分: 不要添加view来做分割线—?使用 ItemDecoration

第二部分: 不要使用padding来做间隔?—使用 ItemDecoration

第三部分: 在GridLayoutManager中高效的绘制decorations

本文是第一部分。

不要用view做分割线 —会影响性能

我曾看到一些开发者在为RecyclerView添加divider的时候采用了一些捷径。原因很简单,ListView原生支持divider,可以直接在xml中设置divider。

<ListView
    android:id="@+id/activity_home_list_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:divider="@android:color/black"
    android:dividerHeight="8dp"/>

  

但是到了RecyclerView,就再也不能直接添加divider了。需要添加一个绘制divider的ItemDecoration。但是开发者发现它很麻烦,于是直接把divider添加到(item的)view上,而不是使用ItemDecoration。

<LinearLayout android:orientation="vertical">
    <LinearLayout android:orientation="horizontal">
        <ImageView />
        <TextView />
    </LinearLayout>
    <View
        android:width="match_parent"
        android:height="1dp"
        android:background="#333" />
</LinearLayout>

  

每当我们走捷径的时候,都有可能会产生副作用。而这里的副作用是可能影响性能。

当在布局中添加了一个divider的时候,我们增加了view的个数。我们都知道view的数目越少会得到越好的性能。有时候增加一个view来实现divider还会增加布局的层级。比如上面的例子中,我们不仅仅增加了一个view,还增加了一个包含它们的 linear layout。为了一个divider而创建了额外的布局。

不要用view做分割线?—会带来副作用

因为divider是view的一部分,所以在item 动画期间,divider也会一起跟着动画。如下图:

显然divider不应该随着item一起做动画。而是和item分开,像这样才是对的:

不要用view做分割线—?缺乏灵活性

如果divider是(item的)view的一部分,那么你就无法控制它。你唯一能控制的就是根据item的position改变divider的可见状态。 而item decoration就灵活多了。

In the above image for the last item in the group divider fills the entire width. Other dividers have a margin of 56dp to their left side. Here is the ItemDecorator’s onDraw code.

在上图中,group最后一个item的divider充满了整个宽度。其它的divider都有一个56dp的左边距。这是这个ItemDecorator的onDraw代码:

@Override
public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
  canvas.save();
  final int leftWithMargin = convertDpToPixel(56);
  final int right = parent.getWidth();

  final int childCount = parent.getChildCount();
  for (int i = 0; i < childCount; i++) {
    final View child = parent.getChildAt(i);
    int adapterPosition = parent.getChildAdapterPosition(child);
    left = (adapterPosition == lastPosition) ?  0 : leftWithMargin;
    parent.getDecoratedBoundsWithMargins(child, mBounds);
    final int bottom = mBounds.bottom + Math.round(ViewCompat.getTranslationY(child));
    final int top = bottom - mDivider.getIntrinsicHeight();
    mDivider.setBounds(left, top, right, bottom);
    mDivider.draw(canvas);
  }
  canvas.restore();
}

  

不要用view做分割线—使用 ItemDecoration

写一个自己的ItemDecoration其实非常简单。你只需要创建一个继承了ItemDecoration的类就可以了。重写 getItemOffsets() 和 onDraw() 方法。具体实现可以参考 这个 示例。

而 25.0.0版本的支持库中,我们有一个新的类 “DividerItemDecoration”。这个类直接实现了divider。

DividerItemDecoration decoration = new DividerItemDecoration(getApplicationContext(), VERTICAL);
recyclerView.addItemDecoration(decoration);

  

提示

  1. 一个RecyclerView可以添加多个ItemDecoration。发挥头脑风暴的时候到了。
  2. 所有decoration都在item绘制之前绘制。如果你想让decoration在view之后绘制,重写onDrawOver() 而不是onDraw() 。

所以下次想为RecyclerView添加分割线的时候,别使用在item布局添加view这种方式了,使用ItemDecoration。

时间: 2024-10-07 19:57:30

深入RecyclerView-为什么要使用ItemDecoration的相关文章

RecyclerView(二)—— ItemDecoration

Recycler没有直接提供设置item间距的功能,而是提供了一个更强大的基类ItemDecoration.类如其名,这个类是Item的装饰.它既可以作为Item的间距,也可以在item之间绘制分隔线,甚至可以对每个item的边缘都进行不同的绘制. ItemDecoration本身是一个虚类,我们在使用时,只能继承它. 先看一个简单版本,这个版本的ItemDecoration只提供一个Item的间距. import android.graphics.Rect; import android.su

RecyclerView探索之通过ItemDecoration实现StickyHeader效果

我在上一篇<小甜点,RecyclerView 之 ItemDecoration 讲解及高级特性实践 > 讲解了 ItemDecoration 的基本用法及它的一些实践,抱着学习研究的态度,这一篇作为实践篇主要目的是尝试通过 ItemDecoration 来实现 RecyclerView 中的 StickyHeader 功能. 关于 StickyHeader 想必大家已经很清楚了,如果不有不清楚的,看下图: 如果要实现 StickyHeader 的话,首先,我们得明白普通的 Header 是怎么

深入理解 RecyclerView 系列之一:ItemDecoration

RecyclerView 已经推出了一年多了,日常开发中也已经彻底从 ListView 迁移到了 RecyclerView,但前两天有人在一个安卓群里面问了个关于最顶上的 item view 加蒙层的问题,被人用 ItemDecoration 完美解决.此时我发现自己对 RecyclerView 的使用一直太过基本,更深入更强大的功能完全没有涉及,像 ItemDecoration, ItemAnimator, SmoothScroller, OnItemTouchListener, Layout

RecyclerView 知识梳理(4) - ItemDecoration

一.概述 通过ItemDecoration,可以给RecyclerView或者RecyclerView中的每个Item添加额外的装饰效果,最常用的就是用来为Item之间添加分割线,今天,我们就来一起学习有关的知识: API DividerItemDecoration解析 自定义ItemDecoration 二.API介绍 当我们实现自己的ItemDecoration时,需要继承于ItemDecoration,并根据需要实现以下三个方法: 2.1 public void onDraw(Canvas

【Android 仿微信通讯录 导航分组列表-上】使用ItemDecoration为RecyclerView打造带悬停头部的分组列表

[Android 仿微信通讯录 导航分组列表-上]使用ItemDecoration为RecyclerView打造带悬停头部的分组列表 一 概述 本文是Android导航分组列表系列上,因时间和篇幅原因分上下,最终上下合璧,完整版效果如下: 上部残卷效果如下:两个ItemDecoration,一个实现悬停头部分组列表功能,一个实现分割线(官方demo) 网上关于实现带悬停分组头部的列表的方法有很多,像我看过有主席的自定义ExpandListView实现的,也看过有人用一个额外的父布局里面套 Rec

Android RecyclerView体验(一)- 简介

在网上关于RecyclerView的基本使用方式已经有了比较详细介绍,而且其设计结构也类似于ListView,所以本文将不重点介绍如何使用,在文末的引用中都可以相关内容.这里主要是介绍RecyclerView的基本功能.设计理念,以及系统提供API的情况. 什么是RecycleView RecyclerView是在Android L(也就是后来的Lollipop)中新加入的一种ViewGroup.但因为它使以support-v7库的形式加入到Android系统中,所以不仅仅是Lollipop版本

RecyclerView完全解析

RecyclerView完全解析 (一) 前言 话说RecyclerView已经面市很久,也在很多应用中得到广泛的使用,在整个开发者圈子里面也拥有很不错的口碑,那说明RecyclerView拥有比ListView,GridView之类控件有很多的优点,例如:数据绑定,Item View创建,View的回收以及重用等机制.那么今天开始我们来重点学习一下RecyclerView控件,本系列文章会包括到以下三个部分: RecyclerView控件的基本使用,包括基础,进阶,高级部分,动画之类 Recy

【FastDev4Android框架开发】RecyclerView完全解析,让你从此爱上它(二十八)

转载请标明出处: http://blog.csdn.net/developer_jiangqq/article/details/49927631 本文出自:[江清清的博客] (一).前言: 话说RecyclerView已经面市很久,也在很多应用中得到广泛的使用,在整个开发者圈子里面也拥有很不错的口碑,那说明RecyclerView拥有比ListView,GridView之类控件有很多的优点,例如:数据绑定,Item View创建,View的回收以及重用等机制.那么今天开始我们来重点学习一下Rec

使用ItemDecoration给RecyclerView 添加水印

前言 项目中有使用到水印效果,如下图所示.在实现过程中,最终选用ItemDecoration来实现,其中有两大步骤:自定义Drawable来完成水印图片.使用ItemDecoration来布局水印. Demo在 WatermarkFragment 中,效果图如下: 1. 自定义Drawable完成水印图片 public class MyDrawable extends Drawable { Paint mPaint; public MyDrawable() { mPaint = new Pain

从头开始学 RecyclerView(五) ItemDecoration 详解

前言 RecyclerView.ItemDecoration,通过名字来看,它就是用来装饰Item的. 在类ListView的视图中,可能需要绘制分隔线:在类GridView的网格视图中,可能需要绘制单元格样式- 这些都可以由重写RecyclerView.ItemDecoration来进行定制. 然后调用mRecyclerView.addItemDecoration(itemDecoration); 即可 分析 看下RecyclerView.ItemDecoration的源码: public s