这些 Drawable 的小技巧,你都了解吗?

这些 Drawable 的小技巧,你都了解吗?

一、前言

在 Android 的开发过程中,Drawable 经常会被用到,一般会用 Drawable 为 View 设置一个显示的效果。而在 Android 下,也提供了很多 Drawable 的默认实现,它们涉及到的内容非常的多,从属性到方法,但是日常生活中,会用到的只有那么些方式。

本文就在工作中,Drawable 的常用方式,整理出一篇文章,会携带一些场景,如有缺漏的,可以在文末留言,本文采用精益编写,如有必要,会一直长期更新。

二、什么是 Drawabe

Drawable 实际上是一个抽象类,主要用于将一个可绘制的资源,按要求绘制成图形,显示在屏幕之上。

Android 为了让开发者更方便的使用 Drawable ,提供了很多 Drawable 的实现类,并提供对应的 xml 的属性配置。

例如:

这些 Drawable 的小技巧,你都了解吗?

同时它也可以使用代码的方式实现,它们的效果是一样的。

这些 Drawable 的小技巧,你都了解吗?

实际上,不管是使用 xml 资源的方式,还是直接在逻辑中硬编码的方式,它们最终显示的效果都是一样的,如下图,一个蓝色的方块:

这些 Drawable 的小技巧,你都了解吗?

Android 中,为我们提供了非常多默认的 Drawable,正常来说,一般是足够我们使用的,它们的关系如下图:

这些 Drawable 的小技巧,你都了解吗?

基本上,从 XxxDrawable 这种类名,就可以看出来它对应的 Xml 资源的命名,唯一需要注意的是 的实现类是 GradientDrawable ,而不是 ShapeDrawable。

三、Drawable 的常用实现

3.1 圆角的按钮

有些 App 中,按钮的圆角,如果背景只是一个纯色或者是简单的规则渐变,是可以使用 来完成的,如前面示例一样。

如果想要为其增加一个圆角,可以在 中使用 corners 属性,它支持设置一个 android:radius ,用来设置四个角落的圆角角度,当然也提供了单独的属性去设置某个角的圆角角度,例如,android:topLeftRadius 就是设置左上的圆角的。

这些 Drawable 的小技巧,你都了解吗?

实现的效果如下:

这些 Drawable 的小技巧,你都了解吗?

3.2 带边框的圆角按钮

想在圆角的 上,加一个边框,可以使用 stroke 属性,当然,不是设置 corners 属性,它就不是一个圆角的效果了。

stroke 用于设置边框,可以指定颜色和边框的宽度。

这些 Drawable 的小技巧,你都了解吗?

可以看到这里指定了一个黄色的边框,效果如下图:

这些 Drawable 的小技巧,你都了解吗?

3.3 单边边框

在 中,如果使用 stroke 来设置边框,它会在四周都加上边框,但是有时候,我们只需要在底部或者单边绘制一个边框的效果,例如:一个列表页里每一项的分割线。

这个时候,就可以使用 ,使用两个 shape 来叠加实现。

这些 Drawable 的小技巧,你都了解吗?

这样的一个 Drawable,如果作为背景的话,显示效果就是在白色背景下,有一条 1px 的灰线。当然其他方向可以参考这个方案,截图发现 1px 的线不太明显,这里就不放图了。

3.4 渐变的背景色

除了支持一个纯色规则图案,它还可以实现渐变的效果,用的最多的,就是线性渐变。

例如一些视频 App 的 UI 设计,会将视频名称直接布局在视频海报上,就可以使用线性渐变的 来实现简单的背景效果,使其在白色的视频海报上,显示的效果依然能看得清楚文字。

例如一般的视频App :

这些 Drawable 的小技巧,你都了解吗?

看到其实海报下面的文字,底部是有一个渐变的背景色的。

这种渐变的效果,可以使用 gradient 标签来设置。

这些 Drawable 的小技巧,你都了解吗?

gradient 支持的属性,基本上看名称就可以知道意思,唯一需要注意的是 android:angle 这个属性,用于设定渐变的角度,但是它不是任何值都支持的,只支持 45 的倍数。

效果如下图:

这些 Drawable 的小技巧,你都了解吗?

3.5 海报的默认图

通常在图片加载的过程中,会为其定义一个默认图片。一般的设计都是会将这个默认图做的非常的简洁,例如中间一个 App 主题的 Icon,然后其它地方纯色铺平。

类似下面这种效果:

这些 Drawable 的小技巧,你都了解吗?

这种默认的图片,当然你可以使用一张等大的图,但是这样不利于适配,不同的 UI 设计尺寸,你需要提供不同的图片。当然你也可以使用 9patch 的图片,但是你会发现有些 density 为 2.75 这种奇葩的手机下,图标会微微偏移,不在正中间。所以这里可以使用一个 的 Drawable 来实现。

是一个带层级效果的 Drawable ,有点类似于布局中的 FrameLayout 的效果。它支持设置多个 Drawable ,并将它们叠加在一起。

所以这样的场景下,我们就需要一个纯色的背景加一张小图,即可实现默认图的效果。

下面是 xml 的实现代码:

这些 Drawable 的小技巧,你都了解吗?

下面是运行后的效果图:

这些 Drawable 的小技巧,你都了解吗?

3.6 带按下效果的按钮

对一个按钮,设计一个按下的效果。可以使用 这个 Drawable。它支持在不同的状态下,显示不同的 Drawable。

同样也支持设置多个 Drawable ,区别在于你需要额外的为每个 Drawable 设置不同的状态,如果不设置,则为默认显示的状态。

这些不同的状态,在 xml 里,都是以 android:state_Xxx 开头来定义的,将其设置为 true 即可生效。

Android 为我们提供了非常多的状态,比较常用的有:

  • state_pressed:按下的效果。
  • state_checkable:是否可设置 checked 状态的效果。
  • state_selected:支持 selected 并且当前处于 selected 的效果。
  • state_checked:支持 checkeable 并且当前处于 checked 的效果。

接下来让我们看一个实际的按钮例子,这里只为其设置按下的效果,xml 代码如下:

这些 Drawable 的小技巧,你都了解吗?

实现效果如下:

这些 Drawable 的小技巧,你都了解吗?

3.7 一个带按下效果的圆角按钮

这个没啥好说的,结合上面的效果就可以做到。你可以选择将它们写在不同的 Drawable 中,也可以在一个 xml 文件中,使用不同 item 来完成。Item 标签是可以支持内部再嵌套一个 Drawable 的。

这些 Drawable 的小技巧,你都了解吗?

3.8 带按下动画

按下效果除了使用 做一个变色的效果之外,在 Api Level 21 之后,可以尝试使用 StateListAnimator 来实现一个 Material Design 的按下效果。

具体细节可以看看我之前的一篇文章:《利用 StateListAnimator 为你的点击加个动画吧!

StateListAnimtor 使用起来非常的简单:

  1. 在 res 中创建一个 animator 目录。
  2. 在其中创建一个 xml 资源文件,就是一个  。
  3. 在 xml 资源中使用  中,定义我们 View 切换状态时候的动画,其实就是一个个 。
  4. 最终将定义好的 animtor 通过 View 的 setStateListAnimator() 方法或者 android:stateListAnimator 属性,设置到 View 上。

举个例子。

首先在 /res/animtor 目录下,创建一个 btn_press_animator.xml 文件。

这些 Drawable 的小技巧,你都了解吗?

可以看到,和 StateListDrawable 一样,它也是通过 android:state_xxx 属性来定义不同的 Animator 的,如果存在多个 Animator ,可以使用 标签将其包裹起来。 这里只是简单的在 state_pressed 的时候,做了一个缩小的动画。

然后,定义一个 View,为其设置属性 android:stateListAnimator="@animator/btn_press_animator"

来看看运行的效果:

这些 Drawable 的小技巧,你都了解吗?

3.9 三角形的 Drawable

假如有类似气泡提示的效果,如下图。

这些 Drawable 的小技巧,你都了解吗?

这样的效果,除了使用 9patch 来实现之外,还可以拿两个 Drawable 来拼接实现,这就需要一个圆角的矩形和一个三角的 Drawable。

三角 Drawable 的实现思路很清奇,是使用一个矩形的 shape ,通过使用 rotate 实现的旋转,来达到尖角的效果。

这些 Drawable 的小技巧,你都了解吗?

这个例子,就是上图的实现效果,是一个黄色的倒三角。如果想要的是一个正三角,只需要改变旋转的角度就可以了。

这些 Drawable 的小技巧,你都了解吗?

3.10 Tint 着色的 Drawable

在 Drawable 中,如果使用的是 BitmapDrawable 或者 NinePatchDrawable(9patch) 的资源的话,可以使用 android:tint 属性为其着色。

默认情况下,待着色的图片资源,会将其所有有颜色地方,都着色成我们指定的颜色,但是会保留透明度。

这些 Drawable 的小技巧,你都了解吗?

效果图如下,上面是原图,下面是使用 tint 之后的效果:

这些 Drawable 的小技巧,你都了解吗?

前面这里给的是 tint 默认的效果,还可以通过 android:tintMode 指定成不同的着色效果,例如下面将 android:tintMode 指定成 screen 之后,效果就完全不一样了。

这些 Drawable 的小技巧,你都了解吗?

3.11 铺平的 Drawable

有时候,作为一些有规则的图片的背景,可以使用一张很小的图片,然后设定 android:tileMode 属性,为其设定一个平铺的效果。

这些 Drawable 的小技巧,你都了解吗?

tileMode 可以指定多个属性值,用于指定不同的效果,以下就是两个比较常用的,上图使用的是 repeat ,下图使用的是 mirror。

这些 Drawable 的小技巧,你都了解吗?

3.12 状态可控的层级 Drawable

如果想要一个 ImageView 上,根据不同的条件显示不同的 Drawable ,可以使用 。从名字上就可以看出它是一个带层级的 Drawable 组合,和 很像,但是区别在于它的显示状态是我们逻辑可控的。最常见的例子是拿它实现一个开关的灯泡,两态的图片,一个表示开灯,一个表示关灯,相信大家应该都见过例子。

今天举一个例子,给某个图标加红点的逻辑。当然我们也可以使用通过一个 FrameLayout 来实现,但是今天我们试试用 来实现它。

这些 Drawable 的小技巧,你都了解吗?

这里使用一个 ,内部根据不同的 maxLevel 和 minLevel 来控制范围,这里只有两态,所以直接让它们取值一致。红点使用 做了一个层叠,在右上角上,直接画了一个大小为 5dp 的红色圆点。

最终我们可以通过 ImageView 的 setImageLevel() 方法来控制显示的内容。

这些 Drawable 的小技巧,你都了解吗?

四、结语

到这里基本上涵盖了 Drawable 大部分的使用场景,在实际例子中学东西是印象最深刻的。当然,Drawable 的使用不止这些,还有一些例如拿 ClipDrawable 来实现一个切割进度的效果之类的,这种还需要写逻辑代码,就不在本文的范围内了,本文主要介绍一些静态能实现的效果。

你只需要掌握最基本的规则,什么 Drawable 能实现什么效果,具体碰到实际需求的时候,再来细致的研究,基本上微调一下就可以使用。

如果你还又什么更有意思的 Drawable 使用技巧,欢迎在文末留言,我们一起讨论一下,如有需要,会持续更新。

今天在承香墨影公众号的后台,回复『成长』。我会送你一些我整理的学习资料,包含:Android反编译、算法、设计模式、虚拟机、Linux、Kotlin、Python、爬虫、Web项目源码。

推荐阅读:

这些 Drawable 的小技巧,你都了解吗?