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

《Android开发艺术探索》读书笔记 (6) 第6章 Android的Drawable

2016-03-09 23:54 393 查看
本节和《Android群英传》中的第六章Android绘图机制与处理技巧有关系,建议先阅读该章的总结

6.1 Drawable简介

(1)Android的
Drawable
表示的是一种可以在
Canvas
上进行绘制的概念,它的种类很多,最常见的就是图片和颜色了。它有两个重要的优点:一是比自定义view要简单;二是非图片类型的drawable占用空间小,利于减小apk大小。
(2)Drawable是抽象类,是所有Drawable对象的基类。
(3)Drawable的内部宽/高可以通过
getIntrinsicWidth
getIntrinsicHeight
方法获取,但是并不是所有Drawable都有内部宽/高。图片Drawable的内部宽高就是图片的宽高,但是颜色Drawable就没有宽高的概念,它一般是作为view的背景,所以会去适应view的大小,这两个方法都是返回-1。

6.2 Drawable分类

http://yaoming168.iteye.com/blog/1633702
http://blog.csdn.net/dj0379/article/details/49764271 http://blog.csdn.net/lonelyroamer/article/details/8243606
(1)BitmapDrawable和NinePatchDrawable   对应标签分别是<bitmap/nine-patch>

<?xml version="1.0" encoding="utf-8"?>
<bitmap / nine-patch
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:tileMode=["disabled" | "clamp" | "repeat" | "mirror"] />

属性分析:

android:src  :就是图片的资源id

android:antialias
:是否开启图片抗锯齿功能。开启后会让图片变得平滑,同时也会一定程度上降低图片的清晰度,建议开启;
android:dither
:是否开启抖动效果。当图片的像素配置和手机屏幕像素配置不一致时,开启这个选项可以让高质量的图片在低质量的屏幕上还能保持较好的显示效果,建议开启。
android:filter
:是否开启过滤效果。当图片尺寸被拉伸或压缩时,开启过滤效果可以保持较好的显示效果,建议开启;
android:gravity
:当图片小于容器的尺寸时,设置此选项可以对图片进行定位,不同的选项可以通过"|"。

android:mipmap  这是一种图像相关的处理技术,叫纹理映射,日常开发不常用。
android:tileMode
:平铺模式,有四种选项
["disabled" | "clamp" | "repeat" | "mirror"]
。当开启平铺模式后,gravity属性会被忽略。repeat是指水平和竖直方向上的平铺效果;mirror是指在水平和竖直方向上的镜面投影效果;clamp是指图片四周的像素会扩展到周围区域,这个比较特别。

NinePatchDrawable
<nine-patch

xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@[package:]drawable/drawable_resource"
android:dither=["true" | "false"]
/>


(2)ShapeDrawable
 对应标签是<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        //当shape为rectangle时使用
android:radius="integer"        //半径值会被后面的单个半径属性覆盖,默认为1dp
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           //指定大小,一般用在imageview配合scaleType属性使用
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(圆环)。默认的shape是矩形,
line
ring
这两种形状需要通过
<stroke>
来制定线的宽度和颜色,否则看不到效果。

针对ring这个形状,android:innerRadius
  android:thickness、android:innerRadiusRatio、android:thicknessRation、android:useLevel

<corners>

这个表示shape的四个角度,这个只适用于矩形shape,用于指圆角的程序

<gradient>

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

   
andoid:angle
指渐变的角度,默认为0,其值必须是45的倍数,0表示从左到右,90表示从下到上

 
     android:centerX  android:centerY渐变的中心点会影响渐变的具体效果

 
    android:gradientRadius   渐变半径  仅当android:type="radial"时有效

 
   android:useLeval   一般为false,  当drawable作为stateListDrawable使用时为true

 
    android:type  渐变的类别,有linear 线性渐变,radial 径向渐变  sweep 扫描渐变

<solid>

 
  表示纯色填充

<stroke>

 
  android:width   描边的宽度

 
  android:color  描边的颜色

 
   android:dashWidth   组成虚线的线段的宽度

 
   android:dashGap  组成虚线的线段之间的间隔,间隔越大则虚线看起来空隙就越大,注意如果android:dashWidth和android:dashGap有任何一个为0,那么虚线效果将不能生效。

<padding>

   这个表示空白有四个属性android:left
 top right bottom

<size>

  有两个属性
android:width和android:height 

(3)LayerDrawble
对应标签
<layer-list>
,表示层次化的Drawable集合,实现一种叠加后的效果。

<layer-list

<item 

   
       android:drawable="@[package:/drawable/drawable_resource]"

   
       androd: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/left/right/bottom
表示drawable相对于view的上下左右的偏移量,单位为像素(dp)。

可能通过layer-list来实现微信文本输入框,也可以用.9图来实现
http://blog.csdn.net/singwhatiwanna/article/details/42215847?utm_source=tuicool&utm_medium=referral
(4)StateListDrawable
对应标签
<selector>
,也是表示Drawable集合,每个drawable对应着view的一种状态。主要用于设置可单击的View的背景,常见的button,

<selector

android:constantSize
= true | false

   
   android:dither = true | false

   
   android:variablePadding = true | false

>

<item

   
       android:drawable="drawable/drawable_resource"

 
        android:state_pressed = true|false

   
      android:state_focused = true |false

   
     等

</selector>

  android:constantSize
 true表示固有大小,false大小会随着状态改变而改变,默认false

android:dither
抖动效果   默认开启true

android:variablePadding
的padding表示是否随着状态改变而改变,默认为false,false表示所有drawble的padding的最大值,不建议开启
一般来说,默认的item都应该放在selector的最后一条并且不附带任何的状态。

(5)LevelListDrawable

对应标签
<level-list>
,同样是Drawable集合,每个drawable还有一个
level
值,根据不同的level,LevelListDrawable会切换不同的Drawable,level值范围从0到100000。
http://blog.csdn.net/lonelyroamer/article/details/8242919
<pre name="code" class="html"><?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>


 http://blog.csdn.net/linghu_java/article/details/42119969  http://blog.csdn.net/sd19871122/article/details/50856952 
(6)TransitionDrawable

对应标签
<transition>
,它用于是吸纳两个Drawable之间的淡入淡出效果。
http://blog.csdn.net/sd19871122/article/details/50856973
<transition xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="@drawable/shape_drawable_gradient_linear"

android:top|right|bottom|left="dimension"

android:id="@[+][package:]id/resource_name"/>

<item android:drawable="@drawable/shape_drawable_gradient_radius"/>
</transition>
TextView = tv = (TextView)findViewById(R.id.test_transition);
TransitionDrawable drawable = (TransitionDrawable) v.getBackground();
drawable.startTransition(5000);

(7)InsetDrawable

对应标签
<inset>
,它可以将其他drawable内嵌到自己当中,并可以在四周留出一定的间距。当一个view希望自己的背景比自己的实际区域小的时候,可以采用InsetDrawable来实现。

<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetBottom="15dp"
android:insetLeft="15dp"
android:insetRight="15dp"
android:insetTop="15dp" 

android:drawable="@drawable/drawable_resource"

>

<shape android:shape="rectangle" >
<solid android:color="#ff0000" />
</shape>

</inset>

        <solid android:color="#ff0000" />

    </shape>

</inset>

 InsetDrawable
表示一个drawable嵌入到另外一个drawable内部,并且在内部留一些间距,这一点很像drawable的padding属性,区别在于 padding表示drawable的内容与drawable本身的边距,insetDrawable表示两个drawable和容器之间的边距。当控件需要的背景比实际的边框小的时候比较适合使用InsetDrawable

(8)ScaleDrawable
对应标签
<scale>
,它可以根据自己的level将指定的Drawable缩放到一定比例。如果level越大,那么内部的drawable看起来就越大。

 ScaleDrawable是对一个Drawable进行缩放操作,可以根据level属性控制这个drawable的缩放比率,也可以设置它在容器中的对齐方式。

        在xml文件中使用scale作为根节点来创建RotateDrawable。

        创建ScaleDrawable的代码如下:

1
<?
xml
 
version
=
"1.0"
 
encoding
=
"utf-8"
?>
2
<!--
android:scaleGravity=""可以设置缩放的对齐方式 -->
3
<
scale
 
xmlns:android
=
"http://schemas.android.com/apk/res/android"

    android:scaleGravity="top|bottom|left|right|center_verticl|fill_vertical等"
4
    
android:drawable
=
"@drawable/smiley_smile"
5
    
android:scaleWidth
=
"100%"
6
    
android:scaleHeight
=
"100%"
7
    
>
8
    
 
9
</
scale
>
直接使用上面的drawable资源是不行的,还必须设置scaleDrawable的等级大于0且小于等于10000的的值,如下

View
testScale = findViewById(R.id.test_scale);

ScaleDrawable
testscaleDrawable = (ScaleDrawable)testScale.getBackground();

testscaleDawable.setLevel(1);

经过上面的两步才能正确的缩放一个drawable,如果少了设置等级这一步,由于默认的等级为0,那么ScaleDrawable将无法显示出来。等级是0到10000之间。
http://yaoming168.iteye.com/blog/1633702   这里下载所有drawable的源码

(9)ClipDrawable

对应标签
<clip>
,它可以根据自己当前的level来裁剪另一个drawable,裁剪方向由
android:clipOrientation
andoid:gravity
属性来共同控制。level越大,表示裁剪的区域越小。

<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:clipOrientation="vertical|horizontal"
android:drawable="@drawable/image1"
android:gravity="bottom|top|left|right|center_vertical等" />

其中gravity比较复杂,需要和clipOriention一起才能发挥作用,在前面已经提到,Drawable的等级(level)是有范围的,即0-10000,最小等级是0,最大等级是10000,对于clipDrawable来说,等级0表示完全裁剪
http://blog.csdn.net/sd19871122/article/details/50856952

6.3 自定义Drawable

(1)Drawable的工作核心就是
draw
方法,所以自定义drawable就是重写
draw
方法,当然还有
setAlpha
setColorFilter
getOpacity
这几个方法。当自定义Drawable有固有大小的时候最好重写
getIntrinsicWidth
getIntrinsicHeight
方法。

(2)Drawable的内部大小不等于Drawable的实际区域大小,Drawable的实际区域大小可以通过它的
getBounds
方法来得到,一般来说它和view的尺寸相同。

其他学习资料:

1.Android样式的开发:shape篇

2.Android样式的开发:drawable篇

3.Android样式的开发:selector篇

4.Android样式的开发:layer-list篇

5.Android样式的开发:Style篇

OK,本章结束,谢谢阅读。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: