Android Drawable必备知识小结
什么是drawable
首先drawable是一个抽象类,表示的是可以在canvas中绘制的图像,常被用作一个view的背景,有多种实现类完成不同的功能。其次drawable大致可以分为这几类:图片、由颜色构成的图像。一般用xml中进行定义。
drawable的继承体系
drawable的实现类及标签
drawable
内部宽高的获取
getintrinsicheight、getintrinsicwidth
- 当drawable由图片构成时方法返回的是图片的宽高
- 当drawable由颜色构成时则没有宽高的概念,返回-1
各类drawable及其用法
bitmapdrawable
用于显示一张图片,如下示例
<?xml version="1.0" encoding="utf-8"?> <bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:antialias="true" android:dither="true" android:filter="true" android:gravity="top" android:src="@mipmap/girl" android:tilemode="repeat" />
常用属性
android:antialias 是否开启抗锯齿
android:dither 是否开启防抖动
android:filter 是否开启过滤效果
android:gravity 用于对图片进行定位
android:src 图片资源id
android:tilemode 平铺模式,repeat、mirror、clamp三种
colordrawable
代表了单色可绘制区域,包装了一种固定的颜色,在画布上绘制一块单色的区域。
示例:
<?xml version="1.0" encoding="utf-8"?> <color xmlns:android="http://schemas.android.com/apk/res/android" android:color="@color/coloraccent"> </color>
还可以用代码创建
colordrawable drawable = new colordrawable(int color); //传入一个color的integer值
ninepatchdrawable
即9-patch图,可以根据内容进行*缩放宽高而不失真
示例:
<?xml version="1.0" encoding="utf-8"?> <nine-patch xmlns:android="http://schemas.android.com/apk/res/android" android:dither="true" android:filter="true" android:src="@color/coloraccent"> </nine-patch>
用draw9patch设定缩放区域
图中1、2方向表示在draw9patch中绘制黑线,黑线长度交集为可拉伸的范围
图中3、4方向黑线长度交集表示内容可以填充的区域
shapedrawable
通过颜色来构造图形,既可以为纯色图形,也可以为具有渐变效果的图形。能构成的图形有rectangle、oval、ring、line
具有渐变效果的圆示例:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <gradient android:angle="45" android:centercolor="@color/coloraccent" android:centerx="50%" android:centery="50%" android:endcolor="@color/colorprimary" android:gradientradius="150dp" android:startcolor="@color/colorprimarydark" android:type="sweep" /> <size android:width="260dp" android:height="260dp" /> </shape>
注意:1、android:angle值必须为45的倍数 2、oval用于绘制椭圆,当size的宽高相等时绘制成圆
圆环示例:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:innerradius="100dp" android:shape="ring" android:thickness="10dp" android:uselevel="false" > <stroke android:width="10dp" android:color="@color/coloraccent" /> </shape>
注:
1、android:uselevel设置为false,否则无法显示理想效果
2、innerradius为圆环内半径,innerradiusration为内半径占圆环宽度的比率,两者以innerradius为主
3、thickness为圆环的宽度,thicknessratio为此宽度占圆环宽度的比率,以thickness为主
常用属性
- android:shape 要绘制的形状,rectangle、oval、ring、line
- <stroke> 形状的描边,有如下属性
- android:width 描边的宽度
- android:color 描边的颜色
- android:dashgap 绘制虚线的线宽
- android:dashwidth 绘制虚线的线段间隔 (要绘制虚线,后两者均不能为0)
-<solid> 纯色填充,android:color指定shape颜色
- <gradient> 渐变效果,与solid不可一起用,有如下属性
- android:angle 渐变的角度,必须为45的倍数
- android:startcolor 渐变的起始颜色
- android:centercolor 渐变的中间颜色
- android:endcolor 渐变的结束颜色
- android:centerx 渐变的中心点横坐标
- android:centery 渐变的中心点纵坐标
- android:gradientradius 渐变半径
- android:type 渐变类型,linear(线性)、sweep(扫视)、radial(径向)
- <corners> 表示矩形(rectangle)的四个角的角度,不适用于其他shape ,有如下属性
- android:topleftradius、android:toprightradius、android:bottomleftradius、android:bottomrightradius 分别为设置左上角、右上角、左下角、右下角的角度
- android:radius 为四角设置相同角度,优先级低,会被其他四个属性覆盖
- <size> shape的宽高,对应着android:width、android:height
- shape默认无宽高,getintrinsicheight、getintrinsicwidth返回-1
- 通过size可以设置其宽高,但作为view背景时任然会被拉伸或缩小为 view大小
- <padding> 设置容纳shape的view的空白间距
statelistdrawable
可以看作是一个状态选择器,通过view不同的状态选择对应的item中的drawable显示
示例:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@color/colorprimarydark" android:state_pressed="false"></item> <item android:drawable="@color/coloraccent" android:state_pressed="true"></item> </selector>
常见状态
android:state_pressed 当按住一个view时,按下的状态
android:state_checked 当一个view被选中时,适用于checkbox
android:state_selected 当一个view被选择时
android:state_enabled 当一个view处于可用状态
android:state_focused 当view获取焦点
layerdeawable
表示的是一种分层的的drawable集合,类似于ps中的图层的概念,将多个drawable放在不同的层上面形成一种叠加的效果
示例:
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@mipmap/night" /> <item android:drawable="@mipmap/photo6" android:gravity="center" /> </layer-list>
注意事项:
1、layer-list可以包含多个item,每个item表示一个drawable,并且后添加的item会覆盖到之前添加的item上面
2、默认情况下,layer-list所有的drawable都会缩放至view大大小,通过设施android:gravity可以调节缩放的效果
3、可以设置上下左右偏移量,android:top、android:bottom、android:left、android:right
levellistdrawable
表示一个drawable集合,集合中的每一个drawable都有一个等级(level),通过设置不同的等级,可以使levellistdrawable切换至不同的drawable。等级范围在0~10000之间, android:maxlevel设置最大level, android:minlevel设置最小level
示例:
<?xml version="1.0" encoding="utf-8"?> <level-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@mipmap/photo0" android:maxlevel="20" android:minlevel="10" /> <item android:drawable="@mipmap/photo1" android:maxlevel="40" android:minlevel="30" /> </level-list>
通过设置level可切换不同的drawable,在代码中
//将imageview的背景切换为photo1, 35 在30~40之间 iv.setimagelevel(35); //将imageview的背景切换为photo0, 15在10~20之间 iv.setimagelevel(15);
transitiondrawable
layerdeawable的子类,用于实现连个drawable的淡入淡出效果
示例:
xml文件定义
<?xml version="1.0" encoding="utf-8"?> <transition xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@mipmap/night" /> <item android:drawable="@mipmap/photo6" /> </transition>
给imageview设置src,在java代码中
iv= (imageview) findviewbyid(r.id.iv_transition); drawable = (transitiondrawable) iv.getdrawable(); drawable.starttransition(1000); // 实现淡入淡出效果 drawable.reversetransition(1000);
insetdrawable
嵌入其他drawable,并可以在四周保留一定的间距
示例:
<?xml version="1.0" encoding="utf-8"?> <inset xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@mipmap/photo6" android:inset="20dp"> </inset>
scaledrawable
根据等级将一个drawable缩放到一定的比例,当level为0时不可见,当level为10000时无缩放效果
示例:
<?xml version="1.0" encoding="utf-8"?> <scale xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@mipmap/night" android:scalegravity="center" android:scaleheight="50%" android:scalewidth="50%" />
要显示出效果,必须设置level大于0
iv = (imageview) findviewbyid(r.id.iv_scale); scaledrawable drawable= (scaledrawable) iv.getdrawable(); drawable.setlevel(1);
- android:scaleheight="percentage",android:scalewidth="percentage",设置宽高缩放为原来的比例为(100%-percentage)
- 设置level越大,图像显示越大
clipdrawable
根据自己的等级(level)来对另一个drawable进行裁剪,裁剪的方向由android:cliporientation、android:gravity共同决定。设置level进行裁剪,level的大小从0到10000,level为0时完全不显示,为10000时完全显示
xml定义
<?xml version="1.0" encoding="utf-8"?> <clip xmlns:android="http://schemas.android.com/apk/res/android" android:cliporientation="horizontal" android:drawable="@mipmap/night" android:gravity="right"></clip>
<imageview android:id="@+id/iv_clip" android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/drawable_clip" />
通过设置level来裁剪
imageview iv = (imageview) findviewbyid(r.id.iv_clip); clipdrawable drawable= (clipdrawable) iv.getdrawable(); drawable.setlevel(5000); // 设置的level越大裁剪的范围越小
属性
android:cliporientation ,horizontal 水平方向裁剪,vertical 垂直方向裁剪
android:gravity ,配合裁剪方向
自定义drawable
自定义圆形drawable
package com.yu.drawablelearing; import android.graphics.bitmap; import android.graphics.bitmapshader; import android.graphics.canvas; import android.graphics.colorfilter; import android.graphics.paint; import android.graphics.pixelformat; import android.graphics.shader; import android.graphics.drawable.drawable; public class circledrawable extends drawable{ private int radius; private int mwidth; private int mheight; private paint mpaint; @override public void draw(canvas canvas) { canvas.drawcircle(mwidth/2,mheight/2,radius,mpaint); } public circledrawable(bitmap bitmap) { radius = math.min(bitmap.getwidth(), bitmap.getheight())/2; mwidth = bitmap.getwidth(); mheight = bitmap.getheight(); bitmapshader bitmapshader = new bitmapshader(bitmap, shader.tilemode.clamp, shader.tilemode.clamp); mpaint = new paint(); mpaint.setshader(bitmapshader); mpaint.setantialias(true); } @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; } @override public int getintrinsicheight() { return mheight; } @override public int getintrinsicwidth() { return mwidth; } }
自定义带圆角的矩形drawable
package com.yu.drawablelearing; import android.graphics.bitmap; import android.graphics.bitmapshader; import android.graphics.canvas; import android.graphics.colorfilter; import android.graphics.paint; import android.graphics.pixelformat; import android.graphics.rectf; import android.graphics.shader; import android.graphics.drawable.drawable; /** * created by pecu on 2016/08/24. */ public class roundrectangledrawable extends drawable { private rectf rectf; private paint mpaint; bitmap mbitmap; @override public void draw(canvas canvas) { canvas.drawroundrect(rectf, mbitmap.getwidth()/6,mbitmap.getheight()/6, mpaint); } public roundrectangledrawable(bitmap bitmap) { mbitmap = bitmap; mpaint = new paint(); bitmapshader bitmapshader = new bitmapshader(bitmap, shader.tilemode.clamp, shader.tilemode.clamp); mpaint.setantialias(true); mpaint.setshader(bitmapshader); } @override public void setalpha(int alpha) { mpaint.setalpha(alpha); invalidateself(); } @override public void setcolorfilter(colorfilter colorfilter) { mpaint.setcolorfilter(colorfilter); invalidateself(); } @override public void setbounds(int left, int top, int right, int bottom) { super.setbounds(left, top, right, bottom); rectf = new rectf(left, top, right, bottom); } @override public int getopacity() { return pixelformat.translucent; } @override public int getintrinsicwidth() { return mbitmap.getwidth(); } @override public int getintrinsicheight() { return mbitmap.getheight(); } }
自定义drawable的一般步骤
1. 自定义drawable类继承自drawable
2. 实现getopacity,setcolorfilter,setalpha等方法
3. 在ondraw方法中进行绘制
4. 若自定义的drawable有固定的大小,则需实现getintrinsicwidth、getintrinsicheight方法
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。