Drawable
在Android开发中,我们会大量的使用到图像元素,这里我主要总结一下Drawable的概念和分类。
Drawable的概念:
Drawable表示图像,这种图像不仅仅是图片,也包含各种颜色组成的图像效果。它常通过XML定义并作为View的背景使用。
drawable的宽高
对于有宽高概念的Drawable,我们可以通过getIntrinsicWidth
和getIntrinsicWidth
进行获取,比如图片。但对于颜色形成的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