Android中的Drawable

来源:互联网 发布:淘宝店铺卖什么升级快 编辑:程序博客网 时间:2024/06/05 11:44

一、Android中有这么几种Drawable:
1、Bitmap File
2、Nine-Patch File
3、Layer List
4、State List
5、Level List
6、Transition Drawable
7、Inset Drawable
8、Clip Drawable
9、Scale Drawable
10、Shape Drawable
下面我们将逐个介绍他们

二、
1、BitmapFile

一个Bitmap,它支持三种格式文件:.png(首选) .JPG(可以接收) .gif(最好不用)。
我们把图片文件放在 res/drawable 目录下,例如res/drawable/filename.png
java文件中引用: R.drawable.filename
在xml中引用” @[package:]drawable/filename

例如:
在xml中引用

<ImageView    android:layout_height="wrap_content"    android:layout_width="wrap_content"    android:src="@drawable/myimage" />

在java中引用

Resources res = getResources();Drawable drawable = res.getDrawable(R.drawable.myimage);

我们还可以编写一个xml用来创建一个BitmapDrawable

<?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: 表示执行的资源文件
android:antialias: 表示是否抗锯齿,开启后会让图片变得平滑,同时也会在一定程度上降低图片的清晰度
android:dither:是否启动抖动效果,开启这个选项可以让高质量的图片在低质量的设备上还能保持较好的显示效果,比如图片的色彩模式为ARGB8888 ,但是设备所支持的色彩模式为RGB565,这个时候开启抖动选项可以使图片不会过于失真。
android:filter:是否开启过滤效果。当图片尺寸被拉伸的或压缩的时候,开启过滤效果可以保持较好的显示效果。
android:gravity:如果bitmap的尺寸小于容器,决定了bitmap所在容器的位置。它的值可以是:
[“top” | “bottom” | “left” | “right” | “center_vertical” |
“fill_vertical” | “center_horizontal” | “fill_horizontal” |
“center” | “fill” | “clip_vertical” | “clip_horizontal”]

android:tileMode:这个选项可以是:[“disabled” | “clamp” | “repeat” | “mirror”]
disabled表示 关闭平铺模式,clamp:图片的四周拉伸到周围区域 ,repeat: 水平和竖值方向的平铺 。 mirror:镜面效果平铺

示例:

<?xml version="1.0" encoding="utf-8"?><bitmap xmlns:android="http://schemas.android.com/apk/res/android"    android:src="@drawable/icon"    android:tileMode="repeat" />

2、 Nine-Patch
.9 图的用法跟普通图的用法类似,这里就不在介绍了
在xml文件中定义NinePatchDrawable 和在xml定义BitmapDrawable也是一样的:

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

3、Layer List
< layer- list > 对应的是LayerDrawable

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

一个layer-list 中可以包含多个item,每个item表示一个Drawable。 Item的结构也比较简单,别叫常用的竖向有 android:top ,android:right, android:left, android:right
他们分别表示Drawable相对于View的上下左右便宜。
Layer-list是有层次概念的,下面的item会赋给上面的item
示例:

?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android">    <item>      <bitmap android:src="@drawable/android_red"        android:gravity="center" />    </item>    <item android:top="10dp" android:left="10dp">      <bitmap android:src="@drawable/android_green"        android:gravity="center" />    </item>    <item android:top="20dp" android:left="20dp">      <bitmap android:src="@drawable/android_blue"        android:gravity="center" />    </item></layer-list>

效果:
这里写图片描述

4、State List
StateListDrawable对应于< selector >标签,它也表示Drawable集合,每个Drawable对应着View的一种状态,这样系统就会根据View的状态来选择合适的Drawable.

<?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"]        android:state_checked=["true" | "false"]        android:state_enabled=["true" | "false"]        android:state_activated=["true" | "false"]        android:state_window_focused=["true" | "false"] /></selector>

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

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

示例:

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:state_pressed="true"          android:drawable="@drawable/button_pressed" /> <!-- pressed -->    <item android:state_focused="true"          android:drawable="@drawable/button_focused" /> <!-- focused -->    <item android:state_hovered="true"          android:drawable="@drawable/button_focused" /> <!-- hovered -->    <item android:drawable="@drawable/button_normal" /> <!-- default --></selector>

5、Level List
LevelListDrawable 对应的标签为< level-list >
它同样表示一个Drawable集合,集合中的每个Drawable都有一个等级的概念,根据不同的等级,LevelListDrawable会切换为相应的Drawable

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

上面的语法中,每个item表示一个Drawable,并且有对应的等级范围,由android:minLevel,android maxLevel来指定。在最小值和最大值之间的等级会对应此item中的drawable。
示例:

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

6、TransitionDrawable
TransitionDrawable 对应于< Transition >标签,它用于两个Drawable之间的淡入淡出效果
语法:

<?xml version="1.0" encoding="utf-8"?><transitionxmlns: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" /></transition>

top、right、bottom、left 表示Drawable四周的便宜
示例:

<?xml version="1.0" encoding="utf-8"?><transition xmlns:android="http://schemas.android.com/apk/res/android">    <item android:drawable="@drawable/on" />    <item android:drawable="@drawable/off" /></transition>
<ImageButton    android:id="@+id/button"    android:layout_height="wrap_content"    android:layout_width="wrap_content"    android:src="@drawable/transition" />
ImageButton button = (ImageButton) findViewById(R.id.button);TransitionDrawable drawable = (TransitionDrawable) button.getDrawable();drawable.startTransition(500);

7、Inset Drawable
InsetDrawable对应的是 < inset >标签,它可以将其他的Drawable内嵌到自己当中,并可以在四周留出一定的距离,当一个View希望自己的背景比自己的实际区域小的时候,可以采用InsetDrawable.
语法:

<?xml version="1.0" encoding="utf-8"?><inset    xmlns:android="http://schemas.android.com/apk/res/android"    android:drawable="@drawable/drawable_resource"    android:insetTop="dimension"    android:insetRight="dimension"    android:insetBottom="dimension"    android:insetLeft="dimension" />

insetTop、insetBottom、insetLeft、insetRight、分别表示顶部、底部、左边、右边内凹的大小。
示例:

<?xml version="1.0" encoding="utf-8"?><inset xmlns:android="http://schemas.android.com/apk/res/android"    android:drawable="@drawable/background"    android:insetTop="10dp"    android:insetLeft="10dp" />

8、Clip Drawable
ClipDrawable 对应于< clip >标签,它可以根据当前的等级(level)乱猜裁剪另一个Drawable,裁剪方向可以通过android:clipOrientation和 andriod:gravity这两个属性来共同控制.
语法:

<?xml version="1.0" encoding="utf-8"?><clip    xmlns:android="http://schemas.android.com/apk/res/android"    android:drawable="@drawable/drawable_resource"    android:clipOrientation=["horizontal" | "vertical"]    android:gravity=["top" | "bottom" | "left" | "right" | "center_vertical" |                     "fill_vertical" | "center_horizontal" | "fill_horizontal" |                     "center" | "fill" | "clip_vertical" | "clip_horizontal"] />

clipOrientation 表示,水平裁剪还是竖直裁剪
gravity需要和clipOrientation结合才能发挥作用。这个简单说明一下就好
gravity = top 结合clipOrientation = vertical 表示从 bottom 开始裁剪
相反 gravity= bottom 结合 clipOrientation = vertical 表示从top开始裁剪
gravity = left 结合clipOrientation = horizontal时,表示从 right开始裁剪
gravity = right 结合clipOrientation = horizontal时,表示从left开始裁剪
具体的参考图:
这里写图片描述

示例:

<?xml version="1.0" encoding="utf-8"?><clip xmlns:android="http://schemas.android.com/apk/res/android"    android:drawable="@drawable/android"    android:clipOrientation="horizontal"    android:gravity="left" />
<ImageView    android:id="@+id/image"    android:background="@drawable/clip"    android:layout_height="wrap_content"    android:layout_width="wrap_content" />
ImageView imageview = (ImageView) findViewById(R.id.image);ClipDrawable drawable = (ClipDrawable) imageview.getDrawable();drawable.setLevel(drawable.getLevel() + 1000);

结果:
这里写图片描述
注意这里的等级 满值为10000,如果设置 1000 表示裁剪 90% 。即
满足 裁剪多少 = (10000 -level)/10000

9、Scale Drawable
ScaleDrawable对应于< scale >,它可以根基自己的等级将指定的Drawable缩放到一定的比例。
语法:

?xml version="1.0" encoding="utf-8"?><scale    xmlns:android="http://schemas.android.com/apk/res/android"    android:drawable="@drawable/drawable_resource"    android:scaleGravity=["top" | "bottom" | "left" | "right" | "center_vertical" |                          "fill_vertical" | "center_horizontal" | "fill_horizontal" |                          "center" | "fill" | "clip_vertical" | "clip_horizontal"]    android:scaleHeight="percentage"    android:scaleWidth="percentage" />

其中 saleGravity跟 shape中的gravity的含义相同。
scaleWidth 、scaleHeight 分别表示对指定Drawable的宽高缩放比
示例:

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

我们查看ScaleDrawable的源码

 @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);        }    }

我们分析 w -= (int) ((w - iw) * (MAX_LEVEL - level) * mState.mScaleWidth / MAX_LEVEL);

由于iw一般都为0 我们化简为:
w -= w * (10000 -level) * mState.mScaleWidth / 10000
mState.mScaleWidth 就是我们设置的缩放比
加入我们设置的 缩放比为 70% 就可以化简为:
w-= w* (1000 -level) * 0.7 /10000

这里我们就会发现 level 越小,我们缩放的程度就会越趋近我们设置的
level越大则越不明显 ,如果level为10000,相当于没有起到效果

所有如果我们向缩放到我们设置的效果,应给level最小值,但又不能为0;
因为源码中有:

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

为0 时 将不绘制
所以上面的示例,如果xml 中写的缩放80% 我们要向就缩放到我们xml定义的80%
我们可以这样:

 Button btn = new Button(getContext());        btn.setBackgroundDrawable(getResources().getDrawable(R.drawable.scale_drawable));        btn.getBackground().setLevel(1);

将level 设为1,这样算出来的缩放比 趋近80%

10、shape Drawable
Shape Drawable 是我们最常用的Drawable。它对应GradientDrawable. 对应的xml标签为:< shape >
语法:

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

android:shape 可以为: rectangle (矩形) 、oval(椭圆)、line (横线) 和ring (圆环) 它默认为矩形、另外line 和 ring这2个选项必须要通过 < stroke >标签来指定宽度和颜色等信息。负责将达不到效果。

针对ring这个形状、有5个特殊的属性:
android:innnerRadius 圆环内半径 和 android:innnerRadiusRatio同时存在时,以android:innerRadius为准。
android:thickness 圆环的厚度,即外半径减去内半径的大小,和android:thicknessRatio同时存在时,以android:thickness为准
android:innerRadiusRatio : 内半径站整个Drawable宽度的比例。默认为9
android:thicknessRatio:厚度站Drawable宽度的比例,默认值为3

< corners >
android:radius 为四个角同时设定角度,优先级比较低
android:topLeftRadius:设定最上角的角度
android:topRightRadius 右上的角度
android:bottomLeftRadius 左下的角度
android:bottomRightRadius 右下的角度

< gradient >
android:angel 渐变的角度默认为0 ,其值必须为45的倍数,0表示 从左到右,90表示从下到上
android:centerX android:centerY 渐变的中心的坐标
android:startColor android:centerColor android:endColor 渐变的其实颜色,中间颜色,最终颜色
android:type 渐变的类型 有 linear(线性渐变) 、radial(径向渐变)、sweep(扫描线渐变)
其中默认为线性渐变
android: android:gradientRadius 渐变的半径 尽到 android:type =”radial”有效

< solid >
通过android:color设置shape的填充颜色

< stroke >
Shape的描边
android:width 描边的宽度
android:color 描边的颜色
android: dashWidth 虚线的宽度
android :dashGap虚线的间隔

< padding>
表示包含该shape的view的空白

< size > 表示给shape的大小

另外画 ring的时候 android:useLevel=”false” ,否则可能不会显示

画line的时候,可能会不显示。网上很多人说要android 3.0 之后关闭硬件加速器,会起到效果。但我试了一下 还是没有显示。我的系统是android 5.0。希望知道原因的朋友留言相告。

我使用的代码:<shape xmlns:android="http://schemas.android.com/apk/res/android"    android:shape="line"    >    <stroke        android:width="10dp"        android:color="#ffff0000"></stroke>    <size android:height="10dp"></size></shape>
        ImageView lineImageView = new ImageView(getContext());        lineImageView.setImageResource(R.drawable.line_shape);        lineImageView.setLayerType(View.LAYER_TYPE_SOFTWARE,null);
0 0
原创粉丝点击