Drawable学习

  • 概念:是一种可以在Canvas上进行绘制的抽象的概念
  • 优点:使用简单,比自定义View的成本低。使用非图片类型的Drawable可减少空间占用。
  • 应用场景:常被用来做View的背景,一般通过xml定义

Drawable宽高可通过getIntrinsicWidth()和getIntrinsicHeight()获取其内部宽/高。实际区域大小可以通过getBounds获取,通常和View的尺寸相同

但并不是所有Drawable都有内部宽/高。

  • 图片所形成的Drawable的内部宽/高就是图片的宽/高。
  • 颜色所形成的Drawable没有内部宽/高的概念。

Drawable类是抽象类,是所有Drawable的基类。继承关系如下:

image.png

Drawable常用子类

ShapeDrawble

可表示纯色、有渐变效果的基础几何图形(矩形,圆形,线条等)。

用法如下:

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="[rectangle | oval | line | ring]"
    <corners
        android:radius="integer"
        android:topLeftRaidus="integer"
        android:topRightRaidus="integer"
        android:bottomLeftRaidus="integer"
        android:bottomRightRaidus="integer" />
    <gradient
        android:angle="integer"
        android:centerX="integer"
        android:centerY="integer"
        android:centerColor="color"
        android:endColor="color"
        android:gradientRadius="integer"
        android:startColor="color"
        android:type="[linear | radial | sweep]"
        android:useLevel="[true | false]" />
    <padding
        android:left="integer"
        android:top="integer"
        android:right="integer"
        android:bottom="integer" />
    <size
        android:width="integer"
        android:height="integer" />
    <solid
        android:color="color" />
    <stroke
        android:width="integer"
        android:color="color"
        android:dashWidth="integer"
        android:dashGap="integer" />

shape:图形的形状。

  • android:shape=["rectangle" | "oval" | "line" | "ring"]
    

    shape的形状,默认为矩形,可以设置为矩形(rectangle)、椭圆形(oval)、线(line)、环形(ring)
    下面的属性只有在android:shape="ring时可用:
    android:innerRadius 内环的半径。
    android:innerRadiusRatio 浮点型,以环的宽度比率来表示内环的半径,
    例如,如果android:innerRadiusRatio,表示内环半径等于环的宽度除以5,这个值是可以被覆盖的,默认为9.

  • android:thickness              环的厚度
    
  • android:thicknessRatio      浮点型,以环的宽度比率来表示环的厚度,
    

    例如,如果android:thicknessRatio="2",
    那么环的厚度就等于环的宽度除以2。这个值是可以被android:thickness覆盖的,默认值是3.

  • android:useLevel  , boolean值         
    

    如果当做是LevelListDrawable使用时值为true,否则为false.

radius:表示shape的四个圆角的角度,只适用于矩形。

  •   android:radius                 整型 半径
    
  •   android:topLeftRadius           整型 左上角半径
    
  •   android:topRightRadius            整型 右上角半径
    
  •   android:bottomLeftRadius          整型 左下角半径
    
  •   android:bottomRightRadius         整型 右下角半径
    

gradient:渐变

  • android:startColor 颜色值 起始颜色

  • android:endColor 颜色值 结束颜色

  • android:centerColor 整型 渐变中间颜色,即开始颜色与结束颜色之间的颜色

  • android:angle 整型

    渐变角度(PS:当angle=0时,渐变色是从左向右。 然后逆时针方向转,当angle=90时为从下往上。angle必须为45的整数倍)

  • android:type ["linear" | "radial" | "sweep"] 渐变类型(取值:linear、radial、sweep)

    linear 线性渐变,这是默认设置
    radial 放射性渐变,以开始色为中心。
    sweep 扫描线式的渐变。

  • android:useLevel ["true" | "false"]

    如果要使用LevelListDrawable对象,就要设置为true。设置为true无渐变。false有渐变色

  • android:gradientRadius 整型

    渐变色半径.当 android:type="radial" 时才使用。单独使用 android:type="radial"会报错。

  • android:centerX 整型 渐变中心X点坐标的相对位置

  • android:centerY 整型 渐变中心Y点坐标的相对位置

padding:与四周空白的距离。

  • android:left 整型 左内边距
  • android:top 整型 上内边距
  • android:right 整型 右内边距
  • android:bottom 整型 下内边距

solid:纯色填充

  • android:color 颜色值 填充颜色

stroke:描边

  • android:width 整型 描边的宽度
  • android:color 颜色值 描边的颜色
  • android:dashWidth 整型 表示描边的样式是虚线的宽度,

值为0时,表示为实线。值大于0则为虚线。

  • android:dashGap 整型 表示描边为虚线时,虚线之间的间隔 即“ ”

size:图形的固有大小,非最终大小。

  • android:width和android:height分别设定shape的宽/高。

参考:Android XML shape 标签使用详解

StateListDrawable

标签selector,表示Drawable集合,每个item都是Drawable,对应View的一种状态

应用场景:如button

<selector xmlns:android="http://schemas.android.com/apk/res/android"
    android:constantSize="[true | false]"
    android:dither="[true | false]"
    android:variablePadding="[true | false]">

    <item
        android:drawable="@drawable/image"
        android:state_pressed="[true | false]"
        android:state_focused="[true | false]"
        android:state_hovered="[true | false]"
        android:state_selected="[true | false]"
        android:state_checkable="[true | false]"
        android:state_checked="[true | false]"
        android:state_enabled="[true | false]"
        android:state_accelerated="[true | false]"
        android:state_window_focused="[true | false]"/>

</selector>
  • android:constantSize:固有大小是否随其状态的改变而改变。
  • android:dither:是否开启抖动效果。
  • android:variblePadding:其padding是否随状态的改变而改变。
  • android:drawable :所引用的位图资源id


    image.png

系统会从上往下的顺序查找,直到找到一条匹配的,如无法匹配会选择默认item,也就是只有drawable属性的item

BitmapDrawable

表示一张图片,设置更多效果

<?xml version="1.0" encoding="utf-8"?>
<bitmap
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@[package:]drawable/drawable_resource"
    android:antialias=["true" | "false"]
    android:dither=["true" | "false"]
    android:filter=["true" | "false"]
    android:mipmap=["true" | "false"]
    android:gravity=["top" | "bottom" | "left" | "right" | "center_vertical" |
                      "fill_vertical" | "center_horizontal" | "fill_horizontal" |
                      "center" | "fill" | "clip_vertical" | "clip_horizontal"]
    android:tileMode=["disabled" | "clamp" | "repeat" | "mirror"] >

</bitmap>
  • android:src: 图片资源id
  • android:antialias:是否开启图片抗锯齿。开启后会让图片会更加平滑,同时清楚度降低。
  • android:dither:是否开启抖动效果。开启后让高质量的图片的比较低质量的屏幕上不失真。
  • android:filter:是否开启过滤效果。当图片尺寸被拉伸或压缩时,开启过滤效果可保持较好的显示效果。
  • android:gravity 图片的对齐效果
可选性 说明
top 保持原有大小,图片至于容器的顶部
bottom 保持原有大小,图片至于容器的底部
left 保持原有大小,图片至于容器的左部
right 保持原有大小,图片至于容器的右部
center_vertical 保持原有大小,图片垂直居中
fill_vertical 图片垂直方向填充容器
center_horizontal 保持原有大小,图片水平居中
fill_horizontal 图片水平方向填充容器
center 保持原有大小,图片同时水平和垂直居中
fill 默认值,同时水平和垂直拉伸
clip_vertical 附加项,表示水平方向的裁剪
clip_horizontal 附加项,表示水平方向的裁剪
  • android:tileMode:平铺模式。可选值的具体含义:

disabled 关闭平铺模式,默认
clamp 大小不变,像素在四周扩散
repeat 常见的水平和垂直方向的平铺
mirror 水平和垂直方向的镜面投影

image.png
image.png
image.png
image.png

LayerDrawable

表示一种层次化的Drawable集合,通过将不同的Drawable放置在不同的层上面从而达到一种叠加后的效果。

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/xxx_id"
        android:drawable="@drawable/drawable_id"
        android:top="dimension"
        android:bottom="dimension"
        android:left="dimension"
        android:right="dimension"/>
</layer-list>

一个layer-list可以包含多个item

  • android:drawable:所引用的位图资源id,如果为空需要有一个Drawable类型的子节点。
  • android:id:层id。
  • android:left:层相对于容器的左边距。
  • android:right:层相对于容器的右边距。
  • android:top:层相对于容器的上边距。
  • android:bottom:层相对于容器的下边距。

还可以结合ShapeDrawable使用,例如

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item>
        <shape android:shape="rectangle">
            <solid android:color="#0ac39e"/>
        </shape>
    </item>
    <item>
        <shape android:shape="rectangle">
            <solid android:color="#0ac39e"/>
        </shape>
    </item>
    <item android:bottom="6dp">
        <shape android:shape="rectangle">
            <solid android:color="#ffffff"/>
        </shape>
    </item>
    <item
        android:bottom="1dp"
        android:left="1dp"
        android:right="1dp">
        <shape android:shape="rectangle">
            <solid android:color="#ffffff"/>
        </shape>
    </item>
</layer-list>

效果图:


image.png

TransitionDrawable

实现两个Drawable之间的淡入淡出效果

常用属性与LayerDrawable相同

实例

<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">

    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/colorPrimaryDark"/>
        </shape>
    </item>
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/colorAccent"/>
        </shape>
    </item>
</transition>

//通过startTransition和reverseTransition实现淡入淡出效果
TransitionDrawable background = (TransitionDrawable) mDrawableTransitionTv.getBackground();
        background.reverseTransition(1000);

LevelListDrawable

  1. 概念:表示一个Drawable集合,集合中的每个Drawable都有一个等级的概念。
  2. 功能:可根据不同等级切换具体的drawable
<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/xxx_id"
        android:drawable="@drawable/drawable_id"
        android:maxLevel="integer"
        android:minLevel="integer"/>
</level-list>
  • android:maxLevel:对应的最大值,取值范围为0~10000,默认为0。(常用)
  • android:minlevel:对应的最小值,取值范围为0~10000,默认为0。

使用方法:

  • 若作为View背景,都需要在Java代码中调用setLevel()方法
  • 若作为ImageView前景,需要调用setImageLevel()。

InsetDrawable

概念:表示一个drawable根据指定的距离嵌入到另外一个drawable内部
应用场景:当控件需要的背景比实际边框小的时候

<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/id"
    android:insetLeft="dimension"
    android:insetTop="dimension"
    android:insetRight="dimension"
    android:insetBottom="dimension"
    android:visible="[true | false]"/>
  • android:drawable:所引用的位图资源id。
  • android:visible:是否留有边距。
  • android:insetTop 与顶部的距离
  • android:insetRight 与右边的距离
  • android:insetBottom 与底部的距离
  • android:insetLeft 与左边的距离

实例

<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetLeft="15dp"
    android:insetTop="20dp"
    android:insetRight="15dp"
    android:insetBottom="5dp"
    android:visible="true">
    <shape android:shape="rectangle">
        <solid android:color="@color/colorAccent"/>
    </shape>
</inset>

效果:

image.png

ScaleDrawable

功能:放缩一定比例

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/id"
    android:scaleGravity="[top | bottom | left | right |
        center_vertical | center_horizontal | center |
        fill_vertical | fill_horizontal | fill |
        clip_vertical | clip_horizontal]"
    android:scaleHeight="percentage"
    android:scaleWidth="percentage">
</scale>
  • android:drawable:所引用的位图资源id。
  • android:scaleGravity:等同于BitmapDrawable的android:gravity。
  • android:scaleWidth/android:scaleHeight:指定Drawable宽/高的缩放比例,以百分比的形式表示。

使用方法:设置控件背景,调用setLevel()方法控制Drawable等级。

  • level取值范围为0~10000。
  • 默认值为0:表示不可见;1~10000:表示可见。

ClipDrawable

<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/id"
    android:gravity="[top | bottom | left | right |
        center_vertical | center_horizontal | center |
        fill_vertical | fill_horizontal | fill |
        clip_vertical | clip_horizontal]"
    android:clipOrientation="[vertical | horizontal]">
</scale>
  • android:drawable :指定截取的源Drawable对象
  • android:clipOrientaton :指定截取方向,可设置水平或垂直截取
  • android:gravity :指定截取时的对齐方式


    image.png

使用方法:设置控件背景,调用setLevel()方法控制裁剪区域大小。

  • level取值范围为0~10000。
  • 0:表示完全裁剪,即不可见;10000:表示不裁剪。
  • level越大,表示裁剪区域越小。

参考:要点提炼|开发艺术之Drawable,Android开发艺术探索(任玉刚)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350