您的位置:首页 > 移动开发 > Android开发

Android开发艺术-第六章Drawable读书笔记

2015-12-17 15:23 501 查看
6.1Drawable的简介

Drawble表示的是一种在Canvas上进行绘制的抽象概念。有很多种类,最常见的就是图片和颜色。有其最重要的两个优点:1.比自定义的view简单;2.非图片类型的drawable比图片占用空间小,可减小APK的大小。

Drawable是一个抽象类,是所有Drawable的基类,比如ShapeDrawable以及BitmapDrawable等等。

Drawable的内部高和内部宽是通过getIntrinsicHeight和getIntrinsicWidth获取的,但不是所有的Drawable类型都有内部高内部宽,一般图片类型的才会有。图片的内部高内部宽都是图片本书的大小,而颜色这种类型的内部宽高则默认是-1.Drawable没有大小的概念,做View背景时一般被拉伸到view的大小。

6.2Drawable的分类

(1).BitmapDrawable和NinePatchDrawable(图片类型;开发中引用原始的图片资源也可通过XML描述,XML描述可设置更多效果)

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/drawable_resource"
android:alpha="0.9"
android:gravity=["top" | "bottom" | "left" | "right" | "center_vertical" |
"fill_vertical" | "center_horizontal"
| "fill_horizontal" | "center" | "fill" |
"clip_vertical" | "clip_horizontal" | "start" | "end"]
android:tintMode=["src_over"|"src_in"|"src_atop"|"multiply"|"screen"|"add"]
android:tint="#ffffff"
android:autoMirrored=["true"|"false"]
android:tileMode=["disabled"|"clamp"|"repeat"|"mirror"]
android:mipMap=["true"|"false"]
android:dither=["true"|"false"]
android:filter=["true"|"false"]
android:antialias=["true"|"false"]
>
</bitmap>


属性介绍:

src :必填项,指定图片资源,只能是图片(可以是.9格式的图片),不能是xml定义的drawable资源

alpha:设置图片透明度,值的范围0.0~1.0,0.0是全透明,1.0是全不透明,API11(3.0)之后的属性

gravity:图片在容器中的位置,默认是fill。其中fill、fill_vertical、fill_horizontal会改变图片的大小,clip_vertical、clip_horizontal会裁剪图片

tintMode:图片着色模式,是API21(Android 5.0)才添加的属性

tint:给图片着色,比如图片本来是其他色的,着色后可以变成设置色

autoMirrored:设置图片是否需要镜像反转,当布局方向是RTL,即从右到左布局时才有用,API19(Android 4.4)才添加的属性

tileMode:设置图片平铺的方式,disabled不做任何平铺,默认设置;repeat图片重复铺满;mirror图片镜像交替(投影)的方式重复图片的绘制;clamp复制图片边缘的颜色来填充容器剩下的空白部分;

mipMap:纹理映射,设置是否可以使用mipmap,API17(4.2)添加的属性

dither:是否设置抖动,图片与屏幕的像素配置不同时会用到,比如图片是ARGB 8888的,而屏幕是RGB565,开启抖动不会让图片过于失真,所以应该开启。

filter:是否开启过滤,当图片被拉伸或者缩小时,开启过滤可以保持很好的显示效果,应该开启

antialias:是否开始图片抗锯齿,开启后图片平滑,但是也会降低图片的清晰度,降低可忽略,所以应该开启。

(2).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:bottomLeftRadius="integer"
android:bottomRightRadius="integer"
android:radius="integer"
android:topLeftRadius="integer"
android:topRightRadius="integer" />
<gradient
android:angle="integer"
android:centerColor="color"
android:centerX="integer"
android:centerY="integer"
android:endColor="color"
android:gradientRadius="integer"
android:startColor="color"
android:type=["linear" | "radial" |"sweep"]
android:useLevel=["true" | "false"] />
<padding
android:bottom="integer"
android:left="integer"
android:right="integer"
android:top="integer" />
<size
android:height="integer"
android:width="integer" />
<solid android:color="color" />
<stroke
android:dashGap="integer"
android:dashWidth="integer"
android:width="integer"
android:color="color" />
</shape>


属性介绍:

shape:图片的形状,rectangle矩形,oval椭圆,line横线,ring圆环,默认矩形。line和ring这两种形状需要通过来制定线的宽度和颜色,否则看不到效果。针对ring这个形状,有5个特殊的属性:innerRadius圆环内半径,和innerRadiusRatio同存在时以innerRadius为准。thickness圆环厚度,外半径减掉内半径的大小,和thicknessRatio同存在以thickness为准;innerRadiusRatio内半径占整个drawable宽度的比例,默认9,如果为n,内半径=宽度/n;thicknessRatio厚度占整个drawable宽度的比例,默认3,如果为n,厚度=宽度/n;userLevel一般使用false,否则无法达到预期,除非它被作为LevelListDrawable使用。

<corners>:shape四个角的角度,只适用矩形shape,radius的优先级最低,会被其他几个属性覆盖;

<gradient>:与<solid>标签互斥,solid表示纯色填充,而它表示渐变效果。angle渐变角度,默认为0,值是45的倍数,0表示从左到右,90是从上到下。centerX渐变的中心点的横坐标;gradientRadius渐变半径,只有当type=radial时有效。useLevel一般为false,当作为StateListDrawable时为true;type渐变类别,linear线性渐变(默认),radial径向渐变,sweep描线渐变。

<solid>:纯色填充

<stroke>:shape描边,dashWidth组成虚线的线段的宽度;dashGap虚线之间的间隔,dashWidth和dashGap任何一个为0则虚线效果不生效。

<size>:ShapeDrawable默认情况下是没有宽高的概念的,但是可以如果指定了size,那么这个时候shape就有了所谓的固有宽高,但是作为view的背景时,shape还是会被拉伸或者缩小为view的大小。

(3).LayerDrawable

层次化的Drawable集合,对应XML标签是<layer-list>,可以包含多个item,下面的item会覆盖遮挡上面的item,达到一种叠加的效果。属性android:top/left/right/bottom表示drawable相对于view的上下左右的偏移量,单位为像素。

(4).StateListDrawable

对应XML的标签<selector>,Drawable集合,每个Drawable对应View的一种状态,根据View的状态选择合适的Drawable。StateListDrawable主要用于View的点击背景。

constantSize是否随着状态改变而改变Drawable的固有大小,false代表随着状态改变而改变,默认为false。state_pressed:按下状态;state_focused:View获取了焦点;state_selected:选择了View;

state_checked:选中了View,适用CheckBox;stata_enabled:View处于可用状态。一般来说,默认的item都应该放在selector的最后一条并且不附带任何的状态,因为系统从上到下的顺序查找。

(5).LevelListDrawable

对应标签<level-list>,Drawable的集合,每个Drawable都对应一个等级,根据等级切换Drawable(setLevel方法)。如果被用来作为ImageView的背景,还可以通过ImageView的setImageLevel方法切换。值的范围:0~10000,默认为0也是最低等级。

(6).TransitionDrawable

对应标签<transition>,用来实现两个Drawable的淡入淡出效果。

transition xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="@drawable/drawable_one"/>
<item android:drawable="@drawable/drawable_two"/>
</transition>


通过它的startTransition和reverseTransition方法来实现淡入淡出效果以及逆过程。

ransitionDrawable drawable = (TransitionDrawable) v.getBackground();
drawable.startTransition(1000);


(7).InsetDrawable

对应<inset>标签,它将其他Drawable内嵌到自己中,并可以在四周留在一定间距。一个View希望自己的背景比自己实际区域小的时候可以采用该实现,LayerDrawable也可以实现这样的效果。insetBottom、

insetLeft、insetRight、insetTop分辨表示各个方向距离边界的大小。

(8).ScaleDrawable

对应标签<scale>,根据等级将Drawable进行一定比例的缩放。scaleWidth和scaleHeight以百分比的形式表示。默认等级为0则无法显示,等级值范围0~10000,等级越大缩放越大。android:useIntrinsicSizeAsMinimum 设置drawable原有尺寸作为最小尺寸,设为true时,缩放基本无效,API Level最低要求为11

(9).ClipDrawable

对应标签<clip>,可根据等级去裁剪一个Drawable,裁剪方向通过clipOrientation和gravity这个两个属性共同控制。level越大,表示裁剪的区域越小。等级0表示完全裁剪整个Drawable都不可见。

android:clipOrientation 设置裁剪的方向, horizontal 在水平方向上进行裁剪,条状的进度条就是水平方向的裁剪;vertical 在垂直方向上进行裁剪

android:gravity 设置裁剪的位置,可取值如下,多个取值用 | 分隔:

top 图片放于容器顶部,不改变图片大小。当裁剪方向为vertical时,会裁掉图片底部

bottom 图片放于容器底部,不改变图片大小。当裁剪方向为vertical时,会裁掉图片顶部

left 图片放于容器左边,不改变图片大小,默认值。当裁剪方向为horizontal,会裁掉图片右边部分

right 图片放于容器右边,不改变图片大小。当裁剪方向为horizontal,会裁掉图片左边部分

center 图片放于容器中心位置,包括水平和垂直方向,不改变图片大小。当裁剪方向为horizontal时,会裁掉图片左右部分;当裁剪方向为vertical时,会裁掉图片上下部分

fill 拉伸整张图片以填满容器的整个高度和宽度。这时候图片不会被裁剪,除非level设为了0,此时图片不可见

center_vertical 图片放于容器垂直方向的中心位置,不改变图片大小。裁剪和center时一样

center_horizontal 图片放于容器水平方向的中心位置,不改变图片大小。裁剪和center时一样

fill_vertical 在垂直方向上拉伸图片以填满容器的整个高度。当裁剪方向为vertical时,图片不会被裁剪,除非level设为了0,此时图片不可见

fill_horizontal 在水平方向上拉伸图片以填满容器的整个宽度。当裁剪方向为horizontal时,图片不会被裁剪,除非level设为了0,此时图片不可见

clip_vertical 附加选项,裁剪基于垂直方向的gravity设置,设置top时会裁剪底部,设置bottom时会裁剪顶部,其他情况会同时裁剪顶部和底部

clip_horizontal 附加选项,裁剪基于水平方向的gravity设置,设置left时会裁剪右侧,设置right时会裁剪左侧,其他情况会同时裁剪左右两侧

6.3自定义Drawable

1)核心就是draw方法,自定义drawable要重写draw方法,当然还有setAlpha、setColorFilter和getOpacity这几个方法。当自定义Drawable有固有大小的时候最好重写getIntrinsicWidth和getIntrinsicHeight方法,自定义颜色填充的Drawable没有固定的大小,没有必要重写,这时内部大小为-1。

(2)Drawable的内部大小不等于Drawable的实际区域大小,Drawable的实际区域大小可以通过它的getBounds方法来得到,一般来说它和view的尺寸相同。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: