本文已经收录到个人Github我的博客,欢迎大佬们光临寒舍:php
个人GIthub博客java
Drawable
简介Drawable
分类Drawable
Drawable
种类繁多,它们都表示一种图像的概念,可是它们不全是图片。在实际开发中,Drawable
常常被用来做为View
的背景使用。android
Drawable
能够方便咱们作出一些特殊的UI效果,这一点在UI相关的开发工做中极为重要。面对UI设计师设计出来的各式各样的按钮点击效果,动态效果,渐变效果,好看是好看,咱们程序员每每会咆哮:"你舒服了,咱们呢!!"别慌,学好Drawable
,你会对各类效果信手拈来,了然于胸,成竹在胸!!git
并且,Drawable
在开发中也有本身的优势:程序员
使用简单,成本低于自定义Viewgithub
非图片类型的Drawable
占用空间较小,对于减小APK大小有所裨益canvas
综上,掌握好Drawable
,走遍天下也不怕!(jia de)swift
Drawable
简介Q1:Drawable
类是抽象类,是全部Drawable的基类。继承关系以下:ruby
Q2:Drawable
使用方式:bash
- 普通控件(非ImageView)是设置
background
- ImageView是设置
src
Q3:内部宽高了解多少?
getIntrinsicWidth()
和getIntrinsicHeight()
注意:
- 并非全部
Drawable
都有内部宽/高- 图片所造成的
Drawable
的内部宽/高就是图片的宽/高。- 颜色所造成的
Drawable
默认状况下没有内部宽/高的概念(除非指定size)。- 内部宽高不等于大小,
Drawable
没有大小概念Drawable
被用做background
的时候,自动被拉伸到View同等大小;Drawable
被用做src
的时候,存放原图大小比例,不会被拉伸
Drawable
种类BitmapDrawable
bitmap
|- src="@drawable/res_id" |- antialias="[true | false]"
|- dither="[true | false]" |- filter="[true | false]" |- tileMode="[disabled | clamp | repeat | mirror]"
|- gravity="[top | bottom | left | right | center_vertical |
| fill_vertical | center_horizontal | fill_horizontal |
| center | fill | clip_vertical | clip_horizontal]" 复制代码
src
:图片的资源idantialias
:是否开启图片抗锯齿。开启后会让图片会更加平滑,同时清晰度下降不多,应该开启。dither
:是否开启抖动效果。开启后让高质量的图片的在低质量的屏幕上显示不失真,应该开启。filter
:是否开启过滤效果。当图片尺寸被拉伸或压缩时,开启后可保持较好的显示效果,应该开启tileMode
:平铺模式。开启后gravity
会失效;可选值的具体含义:
可选项 含义 disable 默认值,关闭平铺模式 mirror 在水平和垂直方向的镜面投影效果 repeat 在水平和垂直方向的平铺效果 clamp 图片四周像素会扩散到其余区域 具体效果:
![]()
gravity
:若位图比容器小,能够设置位图在容器中的相对位置。可选值的具体含义:![]()
- 使用方法:如下两种方法效果相同,图见以前截图中所示的mirror状况。
a.xml:
//在Drawable文件夹中建立bg_tilemode_mirror.xml <?xml version="1.0" encoding="utf-8"?> <bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:dither="true" android:src="@mipmap/ic_launcher" android:tileMode="mirror" > </bitmap> //在activity_main.xml中设置为View背景 <View android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bg_tilemode_mirror" /> 复制代码
b.Java代码:
//在MainActivity建立BitmapDrawable Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher); BitmapDrawable bitDrawable = new BitmapDrawable(bitmap); bitDrawable.setDither(true); bitDrawable.setTileModeXY(Shader.TileMode.MIRROR, Shader.TileMode.MIRROR); //加载到mylayout布局 LinearLayout myLayout = (LinearLayout) findViewById(R.id.mylayout); myLayout.setBackgroundDrawable(bitDrawable); 复制代码
NinePatchDrawable
.9
格式的图片BitmapDrawable
同样NinePatchDrawable
,建议使用XML定义,代码见下。//在Drawable文件夹中建立bg_nine_patch.xml
<?xml version="1.0" encoding="utf-8"?>
<nine-patch xmlns:android="http://schemas.android.com/apk/res/android" android:dither="true" android:src="@drawable/box" >
</nine-patch>
//在activity_main.xml中设置为EditText背景
<EditText android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bg_nine_patch" />
复制代码
ShapeDrawable
shape
,子节点corners
、gradient
、padding
、size
、solid
、stroke
<?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" />
复制代码
接下来分别解释各个节点下属性含义:
Q1 shape
:图形的形状,可选值有:
注意:必须经过
stroke
标签来指定线的宽度和颜色等信息。
- 注意:必须经过
stroke
标签来指定圆环线的宽度和颜色等信息。- 圆环还有额外几个属性,以下图所示:
![]()
Q2 corners
:表示shape的四个圆角的角度,只适用于矩形。
radius
:为四个角同时设定相同的角度。优先级比如下4个属性要低。topLeftRadius
:左上角的角度topRightRadius
:右上角的角度bottomLeftRadius
:左下角的角度bottomRightRadius
:右下角的角度Q3:gradient
:渐变效果,与solid
纯色填充是互斥的。
angle
:渐变的角度。
- 默认为0
- 值必须为45的倍数。
- 0表示从左到右,90表示从下到上。
centerX
:渐变的中心点的X坐标centerY
:渐变的中心点的Y坐标startColor
:渐变的起始色centerColor
:渐变的中间色endColor
:渐变的结束色gradientRadius
:渐变半径。仅当android:type="radial"
时有效useLevel
:通常为false,当Drawable做StateListDrawable
时为truetype
:渐变的类别。可选值:
linear
(线性渐变):默认radial
(辐射渐变):须要配合android:gradientRadius
属性一块儿使用。sweep
(扫描线渐变):![]()
padding
:与四周空白的距离。size
:图形的固有大小,非最终大小
android:width
和android:height
分别设定shape的宽/高。
solid
:纯色填充。
android:color
:指定填充的颜色。
stroke
:描边。属性含义:stroke的属性 | 做用 |
---|---|
width | 描边的宽度 |
color | 描边的颜色 |
dashWidth | 虚线的宽度 |
dashGap | 虚线的空隙的间隔 |
LayerDrawable
layer-list
,经常使用属性:layer-list
|- item
| |- drawable="@drawable/drawable_id"
| |- id="@+id/xxx_id"
| |- top="dimension"
| |- left="dimension"
| |- right="dimension"
| |- bottom="dimension"
|
复制代码
注意:每组 Drawable 由
item
节点进行配置,一个layer-list
可包含多个item,服从下面item覆盖上面item的原则。
A.drawable
:所引用的位图资源id,若是为空须要有一个Drawable类型的子节点。
B.id
:层id。
C.left
:层相对于容器的左边距。
D.right
:层相对于容器的右边距。
E.top
:层相对于容器的上边距。
F.bottom
:层相对于容器的下边距。
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap android:gravity="center" android:src="@mipmap/ic_launcher_round" />
</item>
<item android:left="20dp" android:top="30dp">
<bitmap android:gravity="center" android:src="@mipmap/ic_launcher_round" />
</item>
<item android:left="70dp" android:top="80dp">
<bitmap android:gravity="center" android:src="@mipmap/ic_launcher_round" />
</item>
</layer-list>
复制代码
StateListDrawable
selector
,经常使用属性:selector
|-constantSize="[true | false]" |-dither="[true | false]" |-variablePadding="[true | false]"
|- item | |- drawable="@drawable/drawable_id" | |- state_pressed="[true | false]" | |- state_focused="[true | false]" | |- state_selected="[true | false]" | |- state_hovered="[true | false]" | |- state_checked="[true | false]" | |- state_checkable="[true | false]" | |- state_enabled="[true | false]" | |- state_activated="[true | false]" | |- state_window_focused="[true | false]" | 复制代码
A.selector
:
constantSize
:固有大小是否不变。
默认为false,表示固有大小会随着状态的改变而改变。
设为true,则表示固有大小是固定值,是内部全部Drawable的固有大小中的最大值。
dither
:是否开启抖动效果。开启后让高质量的图片的比较低质量的屏幕上不失真。默认开启。variblePadding
:其padding是否随状态的改变而改变。
- 默认为false,表示padding是固定值,是其内部全部Drawable的padding中的最大值。
- 为true,则表示padding会随着状态的改变而改变。
B.item
:
drawable
:所引用的位图资源id。状态 | 含义 |
---|---|
state_pressed(经常使用) | 按下状态 |
state_focused | 已经获取了焦点 |
state_selected | 选择了View |
state_checked | 适用于checkBox |
state_enabled | 表示可用状态 |
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:constantSize="false" android:dither="true" android:variablePadding="false">
<item android:drawable="@drawable/red_bg" android:state_pressed="false" />
<item android:drawable="@color/black_bg" android:state_pressed="true" />
</selector>
复制代码
LevelListDrawable
Drawable
level-list
,经常使用属性:level-list
|- item
| |- drawable="@drawable/drawable_id"
| |- maxLevel="integer"
| |- minlevel="integer"
复制代码
drawable
:引用的位图资源id。maxLevel
:对应的最大值,取值范围为0~10000,默认为0。(经常使用)minlevel
:对应的最小值,取值范围为0~10000,默认为0。
使用方法:不管是用xml仍是代码实现,若做为View背景,都须要在Java代码中调用setLevel()
方法;若做为ImageView前景,须要调用setImageLevel()
。
加载规则:当某item的android:maxLevel 等于 setLevel所设置的数值时就会被加载。若都没有匹配的则都不显示。
实例:
//在Drawable文件夹中建立bg_level.xml
<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:maxLevel="1" android:drawable="@drawable/image1" />
<item android:maxLevel="2" android:drawable="@drawable/image2" />
<item android:maxLevel="3" android:drawable="@drawable/image3" />
</level-list>
//在activity_main.xml中设置为ImageView背景
<ImageView android:id="@+id/image" android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/bg_level"/>
//在MainActivity调用setImageLevel()
ImageView imageView = (ImageView) findViewById(R.id.image);
imageView.setImageLevel(2);
复制代码
运行结果:ImageView的背景为image2。
TransitionDrawable
transition
,经常使用属性和LayerDrawable
相同,再也不赘述。transition
|- item
| |- drawable="@drawable/drawable_id"
| |- id="@+id/xxx_id"
| |- top="dimension"
| |- left="dimension"
| |- right="dimension"
| |- bottom="dimension"
|
复制代码
使用方法:不管是用xml仍是代码实现,若做为View背景,都须要在Java代码中调用startTransition()
方法才能启动两层间的切换动画,也能够调用reverseTransition()
方法反方向切换。
实例:
//在Drawable文件夹中建立bg_tran.xml
<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/image1"/>
<item android:drawable="@drawable/image2"/>
</transition>
//在activity_main.xml中设置为ImageView的src
<ImageView android:id="@+id/image" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bg_tran" android:src="@drawable/bg_tran"/>
//在MainActivity调用startTransition()
ImageView imageView = (ImageView) findViewById(R.id.image);
TransitionDrawable td = (TransitionDrawable) imageView.getDrawable();
TransitionDrawable td2 = (TransitionDrawable) imageView.getBackground();
td.startTransition(3000);
td2.startTransition(3000);
复制代码
运行结果:ImageView的背景从image1缓缓切换到image2。
InsetDrawable
与Drawable的padding属性不一样:padding表示的是Drawable的内容与Drawable自己的边距;而InsetDrawable表示的是Drawable与容器之间的边距。
inset
,经常使用属性:inset
|- drawable="@drawable/drawable_id"
|- visible="[true | false]"
|- insetTop="dimension"
|- insetLeft="dimension"
|- insetRight="dimension"
|- insetBottom="dimension"
|
复制代码
drawable
:所引用的位图资源id。visible
:是否留有边距。(经测试,发现设置true/false效果同样....)insetTop
:设置距离容器的上边距。其余同理。
//在drawable文件夹下建立
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/image" android:insetBottom="40dp" android:insetLeft="10dp" android:insetRight="30dp" android:insetTop="20dp" android:visible="true">
</inset>
复制代码
效果图:
ScaleDrawable
scale
,经常使用属性:scale
|- drawable="@drawable/drawable_id"
|- scaleGravity="[top | bottom | left | right | center_vertical | center_horizontal | center | fill_vertical | fill_horizontal | fill | clip_vertical | clip_horizontal]"
|- scaleWidth="percentage"
|- scaleHeight="percentage"
|
复制代码
drawable
:所引用的位图资源id。scaleGravity
:等同于BitmapDrawable的android:gravity
。scaleWidth
/android:scaleHeight
:指定Drawable宽/高的缩放比例,以百分比的形式表示。
setLevel()
方法控制Drawable等级。
- level取值范围为0~10000
- 默认值为0:表示不可见;1~10000:表示可见
//在drawable文件夹下建立bg_scale.xml
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/drawable_test" android:scaleGravity="center" android:scaleHeight="70%" android:scaleWidth="70%"/>
//在activity_main.xml中设置为ImageView背景
<ImageView android:id="@+id/image" android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/bg_scale"/>
//在MainActivity调用setLevel()
ImageView imageView = (ImageView) findViewById(R.id.image);
ScaleDrawable scaleDrawable = (ScaleDrawable) imageView.getDrawable();
scaleDrawable.setLevel(1);
复制代码
ClipDrawable
clip
,经常使用属性:scale
|- drawable="@drawable/drawable_id"
|- gravity="[top | bottom | left | right | center_vertical | center_horizontal | center | fill_vertical | fill_horizontal | fill | clip_vertical | clip_horizontal]"
|- clipOrientation="[vertical | horizontal]"
|
复制代码
drawable
:所引用的位图资源id。gravity
:表示对齐方式,须要和clipOrientation一块儿发挥做用。可选值含义:![]()
clipOrientation
:表示裁剪方向,可选值有水平和竖直。
setLevel()
方法控制可见区大小。
- level取值范围为0~10000。
- 0:表示彻底裁剪,即不可见;10000:表示不裁剪。
- level越大可见区越大。
draw()
:系统调用Drawable的draw()
来绘制View的背景或ImageView的图像。draw()
、setAlpha()
、setColorFilter()
、getOpacity()
等方法.如下为自定义Drawable示例://自定义Drawable
public class CustomDrawable extends Drawable {
private Paint mPaint;
public CustomDrawable(int color) {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(color);
}
@Override
public void draw(Canvas canvas) {
final Rect rect = getBounds();
float cx = rect.exactCenterX();
float cy = rect.exactCenterY();
canvas.drawCircle(cx, cy, Math.min(cx, cy), mPaint);
}
@Override
public void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
invalidateSelf();
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
mPaint.setColorFilter(colorFilter);
invalidateSelf();
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
}
复制代码
getIntrinsicWidth()
和getIntrinsicHeight()
,由于它会影响到View的wrap_content布局。注意:Drawable的内部大小不等于Drawable的实际大小,后者可经过
getBounds()
得到,通常它和View的尺寸相同。
恭喜你!已经看到这里了,相信你已经对Drawable
有必定的看法了!本文只是介绍了Drawable
中经常使用的类型,并无彻底列出全部Drawable
的类型,并且只是介绍了XML
的建立。
可是,笔者也给好奇心强的读者准备了一些干货(一篇博客),里面详细介绍了Drawable的各类类型,各类建立方法,总的来讲仍是写得比较不错的。指路:Drawable子类用法总结.
下面展现下本文还没来得及赘述的Drawable
:
若是文章对您有一点帮助的话,但愿您能点一下赞,您的点赞,是我前进的动力
本文参考连接: