android drawable归纳

来源:互联网 发布:中国社交软件大全 编辑:程序博客网 时间:2024/06/11 19:30

Drawable表示一种图像的概念,但drawable并不全是图片,也可以通过颜色构造出各种各样的图像的效果。
Drawable的内部宽高参数比较重要:

drawable.getIntrinsicWidth();drawable.getIntrinsicHeight();

但是并不是所有的Drawable都有内部宽高,一张图片所形成的drawble,其内部宽高就是图片的宽高,但是有颜色形成的drawable,就没有内部宽高的概念。Drawable的内部宽高并不等同于它的大小,一般来说,Drawable是没有大小概念的,当作用View的背景时,Drawable会被拉伸至View的同等大小。

BitmapDrawable

可以直接引用drawable文件,也可以使用xml文件声明,

 BitmapDrawable bitmapDrawable = (BitmapDrawable) getResources().getDrawable(R.drawable.play);
<?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="center"        android:mipMap="true"        android:src="@drawable/play"        android:tileMode="disabled"    />

android:antialias
开启图片抗锯齿功能。开启后图片图片变得平滑,同时也会在一定程度上降低图片的清晰度。

android:dither
开启抖动效果。当图片的像素配置和手机屏幕的像素配置不一致时,开启这个选项可以让高质量的图片在低质量的屏幕上还能保持较好的显示效果,比图图片的色彩模式为ARG8888,但是屏幕所支持的色彩模式为RGB555,这个时候开启抖动选项可以让图片显示过于失真。

android:filter
开启过滤效果。图片尺寸被拉伸或者压缩,开启过滤效果可以保持较好的显示效果

android:gravity
当图片小于容器的尺寸时,设置此选项可以对图片进行定位,可以选填值为:top/bottom/left/right/center_vertical/fill_verticak/fill_horizontal/center/fill/clip_vertical/clip_vertical
clip_vertical:竖直方向的裁剪;
clip_horizontal:水平方方向的裁剪

android:mipMap
图像相关的处理技术,叫纹理映射,默认为false

android:tileMode
平铺模式 选填:disabled/clamp/repeat/mirror
disabled:关闭平铺模式,为默认值。
repeat:简单的水平和竖直方向的平铺效果
mirror:水平和竖直方向上的镜面投影效果
clamp:像素会向四周扩散到周围区域
这里写图片描述

ShapeDrawable

通过颜色来构造的图形,既可以是纯色的图形,也可以是渐变效果的图形。
全局设置:

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"       android:shape="rectangle/oval(椭圆)/line/ring(圆环)"></shape>

corners属性:

 <corners        android:bottomLeftRadius=""        android:bottomRightRadius=""        android:radius=""        android:topLeftRadius=" "        android:topRightRadius=""        />

表示shape的四个角的角度,只适用于矩形shape,这里的角度属于圆角的程度,用px表示。
android:radius:为四个角同时设定相同的角度,优先级较低,会被其他四个属性覆盖。

gradient属性

 <gradient        android:angle=""        android:centerColor=""        android:centerX=""        android:centerY=""        android:endColor=""        android:gradientRadius=""        android:startColor=""        android:type=""        android:useLevel=""        />

与solid标签互斥,solid表示纯色填充,而gradient则表示渐变效果,
android:angle 渐变的角度,默认为0,其值必须为45的倍数,0表示从左到右,90表示从下到上
android:centerX 渐变的中心点的横坐标[默认为shape的宽度中点,20%[20%p]表示shape宽度的20%]
android:centerY 渐变的中心点的竖坐标[默认为shape的高度中点]
android:startColor 渐变的起始色
android:centerColor 渐变的中间色
android:endColor 渐变的结束色
android:gradientRadius 渐变半径,仅当android:type=’radial’时有效
android:userLevel 一般为false,当Drawable作为StateListDrawable使用时为true
android:type 渐变的类别 linear(线性渐变,默认值) radial(径向渐变) sweep(扫描线渐变)

这里写图片描述

solid属性

<solid android:color="" />

标签表示纯色填充

stoke属性

<stroke         android:width=""        android:color=""        android:dashWidth=""        android:dashGap=""        />

android:width 描边的宽度,越大则shape的边缘线就会看起来越粗
android:color 描边的颜色
android:dashWidth 组成虚线的线段的宽度
android:dashGap 组成虚线的线段之间的间隔 间隔越大则虚线看起来空隙就越大

padding属性

<padding android:left=""         android:top=""         android:right=""         android:bottom=""         />

这个表示空白,表示不是shape的空白,而是包含它的View的空白

size属性

    <size         android:width=""        android:height=""        />

width/height 分别表示shape的宽/高,表示shape的固定大小。一般来说并不是shape最终显示的大小,shape并没有宽高的概念,但是作为View的背景它会自适应View的宽/高。

LayerDrawable

LayerDrawable对应XML标签是,表示一种层次化的Drawable集合。一个layer-list中可以包含多个item,每个item表示一个Drawable。
如下仿照微信的输入框:

<?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="#00F000"/>        </shape>    </item>    <item android:bottom="6dp">        <shape android:shape="rectangle">            <solid android:color="#FFF"/>        </shape>    </item>    <item        android:bottom="1dp"        android:left="1dp"        android:right="1dp">        <shape android:shape="rectangle">            <solid android:color="#FFF" />        </shape>    </item></layer-list>

这里写图片描述
效果图如下:
这里写图片描述

StateListDrawable

StateListDrawable对应标签,也表示Drawable集合,每个Drawable都对应着View的一种状态,这样系统就会根据View的状态来选择合适的Drawable。StateListDrawable主要用于设置可单击的View的背景,最常见的是Button。

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"          android:constantSize="true"          android:dither="true"          android:variablePadding="true">    <item android:drawable="@drawable/play" android:state_enabled="true"/>    <item android:drawable="@drawable/play" android:state_focused="true"/>    <item android:drawable="@drawable/play"/></selector>

android:constantSize
StateListDrawable的固有大小是否不随着其状态的改变而改变的,因为状态的改变会导致StateListDrawable切换到具体的Drawable,而不同的Drawable具有不同的固有大小。true表示StateListDrawable的固有大小保持不变,这是它固有大小是内部所有的Drawable的固有大小的最大值,false则会随着状态的改变而改变。默认值为false。

android:dither
是否开启抖动效果

android:variablePadding
StateListDrawable的padding表示是否随着其状态的改变而改变,true表示会随着状态的改变而改变,false表示StateListDrawable的padding是内部所有Drawable的padding的最大值,此选择默认值为false,并且建议不开启选择。

LevelListDrawable

LevelListDrawable对应于标签,它同样表示一个Drawable集合,集合中每个Drawable都有一个等级(level)的概念。根据不同的等级,LevelListDrawable会切换对应的Drawable。

<?xml version="1.0" encoding="utf-8"?><level-list xmlns:android="http://schemas.android.com/apk/res/android">    <item        android:drawable="@drawable/play"        android:maxLevel="100"        android:minLevel="0"/></level-list>

每一个item表示一个Drawable,并且有对应的等级范围,由android:minLevel,android:maxLevel来指定,在最小值和最大值的等级会对应此item中drawable。通过ImageView的setImageLevel方法来切换Drawable。最后,Drawable的等级是有范围,即0~10000,最小等级是0,这是也是默认值。
例子:

<?xml version="1.0" encoding="utf-8"?><level-list xmlns:android="http://schemas.android.com/apk/res/android">    <item        android:drawable="@drawable/etw_c"        android:maxLevel="100"        android:minLevel="0"/>    <item        android:drawable="@drawable/etx_c"        android:maxLevel="200"        android:minLevel="100"/>    <item        android:drawable="@drawable/ety_c"        android:maxLevel="300"        android:minLevel="200"/>    <item        android:drawable="@drawable/etz_c"        android:maxLevel="400"        android:minLevel="300"/>    <item        android:drawable="@drawable/eua_c"        android:maxLevel="500"        android:minLevel="400"/></level-list>

显示效果为:[当然最好的适用方式当然是显示声音的大小]
这里写图片描述

TransitionDrawable

TransitionDrawable对应于标签,它用于实现两个Drawable之间的淡入淡出效果.例如:

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

代码中设置时间:

        ImageView image_view = (ImageView) findViewById(R.id.image_view);        TransitionDrawable drawable = (TransitionDrawable) image_view.getBackground();        drawable.startTransition(8000);

结果为:
这里写图片描述

InsetDrawable

InsetDrawable对应于标签,它可以将其他Drawable内嵌到自己中,并且可以四周留出一定的间距.当一个View希望自己的背景比自己的实际区域小的时候,可以采用InsetDrawable来实现,同时我们知道,通过LayerDrawable也可以这种效果.

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

xml中配置:

    <ImageView        android:layout_width="80dp"        android:layout_height="80dp"        android:background="@drawable/my_inset"/>

实现效果为:

这里写图片描述

ScaleDrawable

ScaleDrawable对应于标签,它可以根据自己的等级(level)将指定的Drawable缩放到一定比例,语法如下:

<?xml version="1.0" encoding="utf-8"?><scale xmlns:android="http://schemas.android.com/apk/res/android"       android:drawable=""       android:scaleGravity=""       android:scaleHeight="percentage"       android:scaleWidth="percentage"></scale>

scaleGravity的含义等同于shape中的android:gravity,android:scaleWidth,android:scaleHeight分别表示对指定Drawable宽和高的缩放比例以百分比的形式表示.
与ScaleDrawable相关的是drawble的等级关系:
ScaleDrawable的onDraw()方法:

 @Override    public void draw(Canvas canvas) {        final Drawable d = getDrawable();        if (d != null && d.getLevel() != 0) {            d.draw(canvas);        }    }

所以要ScaleDrawable可见,需要设置其等级不能为0.
再看onBoundsChange()方法中:

@Override    protected void onBoundsChange(Rect bounds) {        final Drawable d = getDrawable();        final Rect r = mTmpRect;        final boolean min = mState.mUseIntrinsicSizeAsMin;        final int level = getLevel();        int w = bounds.width();        if (mState.mScaleWidth > 0) {            final int iw = min ? d.getIntrinsicWidth() : 0;            w -= (int) ((w - iw) * (MAX_LEVEL - level) * mState.mScaleWidth / MAX_LEVEL);        }        int h = bounds.height();        if (mState.mScaleHeight > 0) {            final int ih = min ? d.getIntrinsicHeight() : 0;            h -= (int) ((h - ih) * (MAX_LEVEL - level) * mState.mScaleHeight / MAX_LEVEL);        }        final int layoutDirection = getLayoutDirection();        Gravity.apply(mState.mGravity, w, h, bounds, r, layoutDirection);        if (w > 0 && h > 0) {            d.setBounds(r.left, r.top, r.right, r.bottom);        }    }

可以看出mDrawable的大小和等级以及缩放比例的关系,以宽度为例:

private static final int MAX_LEVEL = 10000;final int iw = min ? d.getIntrinsicWidth() : 0;w -= (int) ((w - iw) * (MAX_LEVEL - level) * mState.mScaleWidth / MAX_LEVEL);

可以简化为

w -= w * (10000 - level) * mState.mScaleWidth / 10000 ;

当我们的level为10000时,此时w还是以前的w,即没有缩放的效果,当level越大时,那么drawable据看起来越大,当XML中所定义的缩放比例越大,那么内部的Drawable看起越来越小.因为mScaleWidth会变大,则w就会变小.

一下代码可以将背景缩放为原来的20%:

<?xml version="1.0" encoding="utf-8"?><scale xmlns:android="http://schemas.android.com/apk/res/android"       android:drawable="@drawable/app"       android:scaleGravity="center"       android:scaleHeight="80%"       android:scaleWidth="80%"></scale>

当然还需要设置level值,默认的level值drawable将不会绘制,

ImageView iv_scale = (ImageView) findViewById(R.id.iv_scale);ScaleDrawable scaleDrawable = (ScaleDrawable) iv_scale.getBackground();scaleDrawable.setLevel(2) ; //大于0即可

ClipDrawable

ClipDrawable对应于标签,它可以根据自己当前的等级(level)来裁剪另一个drawable,裁剪方向可以通过android:clipOrientation和android:gravity这两个属性来共同控制.

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

当然也是要设置level的,不然也不会显示的.由于ClipDrawable用的比较少,一般在开发中也是直接设置图片,这里就不做笔记了.

后记:
基本上把用得比较多的drawable都理了一遍,有些不对的地方慢慢改正.要睡觉了,搞太多了……

0 0