Android中的Drawable

Posted 痕迹天涯119

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android中的Drawable相关的知识,希望对你有一定的参考价值。

Drawable

android开发中,我们会大量的使用到图像元素,这里我主要总结一下Drawable的概念和分类。

Drawable的概念:

Drawable表示图像,这种图像不仅仅是图片,也包含各种颜色组成的图像效果。它常通过XML定义并作为View的背景使用。

drawable的宽高

对于有宽高概念的Drawable,我们可以通过getIntrinsicWidthgetIntrinsicWidth进行获取,比如图片。但对于颜色形成的Drawable则不存在宽高的概念。

本文主要总结常用的Drawable并保持更新。


BitmapDrawable

这是最普遍的一类Drawable类。一张原始的位图即可,也可以通过XML进行定义。

<?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:gravity=["top" | "bottom" | "left" | "right" | "center_vertical" |
                      "fill_vertical" | "center_horizontal" | "fill_horizontal" |
                      "center" | "fill" | "clip_vertical" | "clip_horizontal"]
    android:mipMap=["true" | "false"]
    android:tileMode=["disabled" | "clamp" | "repeat" | "mirror"] />

android:src
类型:Drawable resource。 引用资源的ID
android:antialias
类型:Boolean。是否开启抗锯齿。
android:dither
类型:Boolean。如果位图与屏幕的像素配置不同时,是否允许抖动.(例如:一个位图的像素设置是 ARGB 8888,但屏幕的设置是RGB 565,开启后可以在低质量的屏幕上保持较好的显示效果)
android:filter
类型:Boolean。是否允许对位图进行过滤。对位图进行收缩或者延展使用过滤可以获得平滑的外观效果。
android:gravity
类型:关键字。定义位图的重力(gravity),如果位图小于其容器,使用重力指明在何处绘制
android:titleMode
参数对应:
关闭平铺|水平和竖直平铺|倒影屏幕|拉伸平铺(可自行演示)
android:mipMap
纹理映射,默认false。

Nine-PatchDrawable

可以根据宽高自动缩放并保证不失真

使用方式:

<?xml version="1.0" encoding="utf-8"?>
<nine-patch
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@[package:]drawable/drawable_resource"
    android:dither=["true" | "false"] />

推荐一篇制作教程:http://www.ui.cn/detail/48906.html,使用AS也可以编辑.9图,将drawable文件后缀前添加.9即可。

ShapeDrawable

XML定义属性:

<?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:topLeftRadius="integer"
        android:topRightRadius="integer"
        android:bottomLeftRadius="integer"
        android:bottomRightRadius="integer" />
    <gradient
        android:angle="integer"
        android:centerX="float"
        android:centerY="float"
        android:centerColor="integer"
        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>

shape根标签

android:shape
关键字。定义shape的形状
“rectangle” 矩形,默认值
“oval” 椭圆
“line” 一条水平的直线。
“ring” 圆环
line和ring必须使用<stroke标签来指定线的宽度和颜色等信息。

下面的属性只有当 android:shape="ring"才使用:

android:innerRadius
尺寸。 内环的半径。一个尺寸值(dip等等)或者一个尺寸资源。
android:innerRadiusRatio
Float类型。这个值表示内部环的比例,例如,如果android:innerRadiusRatio = ” 5 “,那么内部的半径等于环的宽度除以5。这个值会被android:innerRadius重写。 默认值是9。
android:thickness
尺寸。环的厚度,是一个尺寸值或尺寸的资源。
android:thicknessRatio
Float类型。厚度的比例。例如,如果android:thicknessRatio= ” 2 “,然后厚度等于环的宽度除以2。这个值是被android:innerRadius重写, 默认值是3。
android:useLevel
Boolean类型。如果用在 LevelListDrawable里,那么就是true。如果通常不出现则为false。


shape内部标签

corners

为Shape创建一个圆角,只有shape是rectangle时候才使用。
属性:
android:radius
Dimension。为四个角设定相同的角度,优先级较低,会被其他四个属性覆盖。

android:topLeftRadius
Dimension。top-left 圆角的半径。
android:topRightRadius
Dimension。top-right 圆角的半径。
android:bottomLeftRadius
Dimension。 bottom-left圆角的半径。
android:bottomRightRadius
Dimension。bottom-right圆角的半径。
注意:每个圆角半径值都必须大于1,否侧就没有圆角。

gradient

指定这个shape的渐变颜色。
属性:
android:angle: Integer。渐变的角度。 0 代表从 left 到 right。90 代表bottom到 top,依次旋转。必须是45的倍数,默认为0
android:startColor: 开始的颜色值。
android:centerColor: 可选的颜色值。基于startColor和endColor之间。
android:endColor: 结束的颜色
android:centerX: 渐变中心的相对X坐标,在0到1.0之间。
android:centerY: 渐变中心的相对Y坐标,在0到1.0之间。
android:gradientRadius: 渐变的半径。只有在 android:type=”radial”才使用

android:type
渐变的模式,下面值之一:
“linear” 线形渐变。这也是默认的模式
“radial” 辐射渐变。startColor即辐射中心的颜色
“sweep” 扫描线渐变。
android:useLevel: 如果在LevelListDrawable中使用,则为true

padding

包含该drawable的空白

主要有以下属性:
android:left
Dimension。左边填充距离.
android:top
Dimension。顶部填充距离.
android:right
Dimension。右边填充距离.
android:bottom
Dimension。底部填充距离.

Size

为shape设定一个固有宽高(虚拟存在,可通过getIntrinsicXXX获取,但依旧会伸缩)

属性:
android:height
Dimension。这个shape的高度。
android:width
Dimension。这个shape的宽度。

solid

纯色填充

属性:
android:color

stroke

shape的描边,前面已经提到。
属性:
android:width:笔画的粗细。
android:color:笔画的颜色
android:dashGap:虚线之间的间隔
android:dashWidth:每画一条线的长度。
后面两个属性必须同时设置有效值,否则都无效。

绘制一条虚线

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="line">
    <stroke
        android:color="@color/kpi_grey_dashed_color"
        android:width="1dp"
        android:dashGap="2dp"
        android:dashWidth="6dp"/>
</shape>

然而在实际使用中并不会如愿显示,请保证在引用时为该虚线设置的高度高于这里设置的width属性,且设定软解码,如下

        <ImageView
            android:id="@+id/iv_segment"
            android:layout_width="40dp"
            android:layout_height="2dp"
            android:layout_gravity="center_vertical"
            android:scaleType="fitXY"
            android:layerType="software"
            android:src="@drawable/ic_kpi_dashed"/>

Layer List

层次化的Drawable,管理一组其他的Drawable对象,通过各种叠加能实现各种特殊的效果。

<?xml version="1.0" encoding="utf-8"?>
<layer-list
    xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:drawable="@[package:]drawable/drawable_resource"
        android:id="@[+][package:]id/resource_name"
        android:top="dimension"
        android:right="dimension"
        android:bottom="dimension"
        android:left="dimension" />
</layer-list>

每个item标签对应一个drawable,其他四个属性对应该item相对应layer的偏移量,常用于实现卡片的阴影效果和View边框效果等
例1:
给一个View上下设置黑色边框,左右不变色

    <item>
        <shape
            android:shape="rectangle">
            <stroke android:width="1dp" android:color="#FF000000" />
            <solid android:color="#FFDDDDDD" />
        </shape>
    </item>

    <item android:top="1dp" android:bottom="1dp">
        <shape
            android:shape="rectangle">
            <stroke android:width="1dp" android:color="#FFDDDDDD" />
            <solid android:color="#00000000" />
        </shape>
    </item>

例2:曾经的微信小框可以这样做

    <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>

评价:自由灵活度高,但使用得当能省很多事

State List

<?xml version="1.0" encoding="utf-8"?>
<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="@[package:]drawable/drawable_resource"
        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"]//手动表明View的当前状态
        android:state_checked=["true" | "false"]//选定
        android:state_enabled=["true" | "false"]//手动表明View的状态状态
        android:state_activated=["true" | "false"]//
        android:state_window_focused=["true" | "false"] />
</selector>

android:constantSize
Drawable固有大小是否随着状态的改变(切换drawable)而变化,默认false
android:dither
防抖动,默认开启
android:variablePadding
Drawable内的padding是否随着状态而改变

常用实例(ToggleButton):

    <RadioGroup
        android:layout_margin="10dp"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <RadioButton
            android:id="@+id/Left_message_radio"
            android:text="消息"
            android:textSize="20sp"
            android:gravity="center"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="40dp"
            android:checked="true"
            android:background="@drawable/left_radio_drawable"
            android:textColor="@drawable/radio_text_color"
            android:button="@null" />

        <RadioButton
            android:id="@+id/right_message_radio"
            android:text="电话"
            android:textSize="20sp"
            android:gravity="center"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="40dp"
            android:background="@drawable/right_radio_drawable"
            android:textColor="@drawable/radio_text_color"
            android:button="@null" />
    </RadioGroup>

left_radio_drawable

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/left_button_checked" android:state_checked="true" /> <!-- pressed -->
    <item android:drawable="@drawable/left_button_normal" /> <!-- default -->
</selector>

left_button_checked

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners
        android:bottomLeftRadius="5dp"
        android:topLeftRadius="5dp"/>
    <stroke
        android:width="1dp"
        android:color="#ffffff"/>
    <solid
        android:color="#ffffff"/>
</shape>

left_button_normal

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners
        android:bottomLeftRadius="5dp"
        android:topLeftRadius="5dp"/>
    <stroke
        android:width="1dp"
        android:color="#ffffff"/>
    <solid
        android:color="#9997ffff"/>
</shape>

右边Radio的效果是类似的,这里就不发了,可以自己动手整一下哈哈

radio_text_color

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="#000000"  android:state_checked="true"/>
    <item android:color="#ffffff"  android:state_checked="false"/>
</selector>

该drawable用于动态更改Radio中text的颜色,可能会有人疑问是否可以直接在java文件中同setText方法根据点击事件来设置颜色呢?答案是:不能,别问我为啥子不能,我也不知道,有明白的可以留言分享下。

最后在Activity中通过点击事件切换一下checked状态即可,OK,效果如下

模拟器上看起来比较龊,大家迁就着吧,,,

Vector Drawable

Vector Drawables是5.0后新增的,显示效果是通过path路径进行绘制,可以自动适应任何大小的屏幕和分辨率,体积也小的不行,真正实现一套图标到处使用

定义

<!-- res/drawable/ic_heart.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="256dp"
    android:width="256dp"
    android:viewportWidth="32"
    android:viewportHeight="32">
  <!-- draw a path -->
  <path android:fillColor="#c9c10606"
      android:pathData="M20.5,9.5
                        c-1.955,0,-3.83,1.268,-4.5,3
                        c-0.67,-1.732,-2.547,-3,-4.5,-3
                        C8.957,9.5,7,11.432,7,14
                        c0,3.53,3.793,6.257,9,11.5
                        c5.207,-5.242,9,-7.97,9,-11.5
                        C25,11.432,23.043,9.5,20.5,9.5z" />
</vector>

使用:
注意是通过srcCompat引用,可以更好的向下兼容

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <ImageView  
      android:layout_width="wrap_content"  
      android:layout_height="wrap_content"  
      app:srcCompat="@drawable/ic_heart" />  
</RelativeLayout>

演示:

在AS中Google已经为广大吃瓜群众提供了一套,可自行取用,如图

如果你在5.0之前的版本中动态使用Vector,请follow以下方式

// Use AppCompatResource so that it will accurately use theme attributes
Drawable drawable = AppCompatResources.getDrawable(R.drawable.ic_test_24dp);

OK,常用的也差不多了,其他还有好几个不太常用的,以后慢慢增加,,,


参考文章:
http://guides.codepath.com/android/Drawables
https://developer.android.com/guide/topics/resources/drawable-resource.html

本文最新更新时间___2017.04.6

以上是关于Android中的Drawable的主要内容,如果未能解决你的问题,请参考以下文章

android studio中drawable怎么用

solidworks中的一些标注尺寸的技巧

需要调整 Android ImageView 的大小以匹配不断变化的 Drawable 大小

iOS和Android的APP启动图标和应用商店截图尺寸

Android适配——drawable和values的加载规则

如何在 ImageView 中获取 Drawable 的尺寸? [复制]