六、Drawable

来源:互联网 发布:传奇地图编辑器软件 编辑:程序博客网 时间:2024/05/16 09:11

掌握Drawable可以做出一些特殊的效果.

1.Drawable的内部宽高

通过getIntrinsicWidth和getIntrinsicHeight这两个方法可以获取到。并不是所有的Drawable都有内部宽高,比如一张图片所形成的的Drawable,它的内部宽高就是图片的宽高,但是一个颜色所形成的的Drawable,就没有内部宽高的概念。
另外需要注意的是,Drawable的内部宽高不等同于它的大小,一般来说,Drawable是没有大的概念的,当用作View的背景的时候,Drawable会被拉伸至View的同等大小。

2.Drawable的分类

2.1.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"] />

表示的就是一张图片,在实际的开发中,可以直接引用原始的图片即可,也可以通过xml的方式来描述。
src:图片的资源id

antialias:是否开启图片的抗锯齿,开启后会让图片更加圆滑,同时会在一定的程度上面降低图片的清晰度,但是这个降低的幅度较低以至于可以忽略。因此抗锯齿选项应该开启。

dither:是否开启抖动效果。根据分析,抖动效果应该开启。

filter:是否开启过滤效果。当图片尺寸被拉伸或者压缩的时候,开启过滤效果可以保持较好的显示效果,因此应当开启。

gravity:当图片的尺寸小于容器的尺寸的时候,设置此选项可以对图片进行定位。

mipMap:图片相关的处理技术叫纹理映射,默认值为false,开发中此选项不常用。

tileMode:平铺模式。disabled表示关闭平铺模式,默认值。当开启平铺模式之后gravity属性会被忽略。

repeat表示简单的水平和竖直方向的平铺效果;

mirror表示在水平和竖直方向上的镜面投影效果;

clamp表示图片四周的像素会扩展到周围区域。

2.2.NinePatchDrawable

<?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"] />

xml中的属性和BitmapDrawable中标签的属性是一样的,表示一张.9格式的图片。.9图片可以自动地根据所需的宽/高进行相应的缩放并保证不失真,和BitmapDrawable一样,在实际开发中可以直接引用,实际使用过程中发现bitmap标签也可以使用.9图。

2.3.ShapeDrawable

<?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="integer"        android:centerY="integer"        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:图形的形状,矩形,椭圆,横线,圆环,默认矩形,另外,line和ring这两个选项必须通过stroke指定闲的宽度和颜色等信息。

针对ring这个环状,有5个特殊的属性:
android:innerRadius圆环的内半径,和android:innerRadiusRatio同时存在时,以android:innerRadius为准。
android:innerRadiusRatio内半径占整个Drawable宽度的比例,默认为9。如果为n,那么内半径=宽度/n
android:thickness圆环的厚度,即外半径减去内半径的大小,和android:thicknessRatio同时存在时,以android:thickness为准。
android:thicknessRatio厚度占整个Drawable宽度的比例,默认值为3。如果为n,那么厚度=宽度/n
android:useLevel一般应该使用false,否则有可能无法达到预期的显示效果,除非被当做LevelListDrawable。

corners:表示shape的四个角的角度。只适用于矩形shape,这里的角度指的是圆角的程度用px来表示。

android:radius为四个角同时设定相同的角度,优先级较低,会被其他四个属性覆盖。
android:topLeftRadius设定左上角的角度
android:topRightRadius设定右上角的角度
android:bottomLeftRadius设定左下角的角度
android:bottomRightRadius设定右下角的角度

gradient:与solid标签是互相排斥的,其中solid表示纯色填充,而gradient表示渐变效果。

android:angle渐变的角度。默认为0,其值必须为45的倍数,0表示从左到右,90表示从下到上。
android:centerX渐变的中心点的横坐标
android:centerY渐变的中心点的纵坐标
android:startColor渐变的起始色
android:centerColor渐变的中间色
android:endColor渐变的结束色
android:gradientRadius渐变半径,仅当android:type为radial有效
android:useLevel一般为false,当Drawable作为StateListDrawable使用时为true
android:type渐变的类型,有linear线性渐变,radial径向渐变,sweep扫描线渐变三种,默认为线性渐变。

solid:这个表示纯色填充,通过color即可指定shape中填充的颜色。

stroke:shape的描边。
android:width描边的宽度,越大则shape的边缘线就会看起来约粗
android:color描边的颜色
android:dashWidth组成虚线的线段的宽度
android:dashGap组成虚线的线段之间的间隔,间隔越大看起来空隙就越大
注意:如果android:dashWidth和android:dashGap有任何一个为0,那么虚线效果将不能生效

padding:表示空白,但是它表示的不是shape的空白,而是包含它的view的空白。

size:shape的大小,属性android:width,android:height。

表示shape的固有大小,一般来说不是shape最终显示的大小,shape没有宽高的概念,作为view的背景会自适应view的宽高。Drawable的两个方法getIntrinsicWidth和getIntrinsicHeight表示的是Drawable的固有宽高,对于有些Drawable比如图片来说,它的固有宽高就是图片的尺寸,对于shape来说,默认情况下,它是没有固有宽高这个概念的,这个时候那两个方法就会返回-1,但是如果通过size标签设置宽高信息,shape就有了所谓的固有宽高。

总结来说,size标签设置的宽高就是ShapeDrawable的固有宽高,但是作为view的背景时,shape还会被拉伸或者缩小为view的大小。

2.4.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>

表示一种层次化的Drawable集合,通过将不同的Drawable放置在不同的层上面从而达到一种叠加后的效果。这些属性分别表示Drawable相对于View的上下左右的偏移量。

类似微信的文本输入框:

<?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="#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></layer-list>

2.5.StateListDrawable

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

表示Drawable集合,每个Drawable对应着View的一种状态,这样系统就会根据View的状态来选择合适的Drawable。
属性:
android:constantSizeDrawable的固有大小是否不随着其状态的改变而改变,默认值为false。
android:dither抖动效果是否开启,默认为true
android:variablePaddingDrawable的padding表示是否随着状态的改变而改变,默认false。
item标签表示一个具体的Drawable。

2.6.LevelListDrawable

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

表示Drawable集合,集合中的每个Drawable都有一个等级的概念,根据不同的等级,Drawable会切换为对应的Drawable。
作为View的背景的时候,可以通过Drawable的setLevel方法来设置不同的等级从而切换具体的Drawable,被用作ImageView的前景时,可以通过ImageView的setImageLevel方法来切换Drawable。范围0-10000。

2.7.TransitionDrawable

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

表示两个Drawable之间的淡入淡出效果。
可以使用它的startTransition和reverseTransition方法来实现淡入淡出的效果以及它的逆过程。

2.8.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" />

可以将其他Drawable内嵌到自己当中,并可以在四周留出一定的间距。当一个view希望自己的背景比自己的实际区域小的时候,可以采用它实现。

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

shape距离view的边界15dp。

2.9.ScaleDrawable

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

可以根据自己的等级level将指定的Drawable缩放到一定的比例。android:scaleHeight,android:scaleWidth分别表示对指定Drawable宽和高的缩放比例,以百分比的形式表示。想要ScaleDrawable可见,需要等级不能为0。范围0-10000。

<?xml version="1.0" encoding="utf-8"?><scale xmlns:android="http://schemas.android.com/apk/res/android"    android:drawable="@drawable/image_bg"    android:scaleHeight="70%"    android:scaleWidth="70%"    android:scaleGravity="center" />View testScale = findViewById(R.id.test_scale);ScaleDrawable testScaleDrawable = (ScaleDrawable) testScale.getBackground();testScaleDrawable.setLevel(10);

2.10.ClipDrawable

<?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"] />

可以根据自己的等级level来裁剪另一个Drawable。

将一张图片从上到下裁剪:

<?xml version="1.0" encoding="utf-8"?><clip xmlns:android="http://schemas.android.com/apk/res/android"    android:clipOrientation="vertical"    android:drawable="@drawable/image_bg"    android:gravity="bottom" />ImageView testClip = (ImageView) findViewById(R.id.test_clip);ClipDrawable testClipDrawable = (ClipDrawable) testClip.getDrawable();testClipDrawable.setLevel(8000);

等级设置为8000表示,裁剪2000,在顶部裁掉20%。

0 0
原创粉丝点击