微信号:androidwalker

介绍:关注Android新技术、进阶开发

大话Android Drawable类型<上>

2016-03-31 07:41 Android高级开发

    一个Drawable资源,就是一个可以被绘制在屏幕上的图像通用概念。

    你可以通过在XML里面使用一些特殊的属性来应用这些drawable资源, android:drawable 和android:icon. Drawable可以分为以下几种类型:

    • Bitmap 文件

      bitmap格式可以是 (.png.jpg, 或是.gif). 相应的Java类是 BitmapDrawable.

    • Nine-Patch 文件

      png格式文件,可以基于内容做尺寸上的缩小或放大 (.9.png). 相关Java类NinePatchDrawable.

    • Layer 列表

      顾名思义,它是由多个Drawable按层级组成的,可以定义在XML中. 系统会按顺序去渲染这些Drawable. 相关Java类 LayerDrawable.

    • State 列表

      也是多张图片,不同的是它是根据状态来显示不同的图片。与Layer列表的区别在于Layer列表会把所有的图片都绘制出来,而它不会。可以定义在XML中 (比如一个按钮不同的显示不同的背景图). 相关Java类 StateListDrawable.

    • Level 列表

      XML定义多张可供选择的Drawabble资源, 每一个分配一个最大数字值. 相关Java类 LevelListDrawable.

    • Transition Drawable

      一个XML里面定义一张Drawable,可以被插在两张Drawable之间做交叉渐变效果。相关Java类TransitionDrawable.

    • Inset Drawable

      可以在XML里面,定义一张Drawable,可以通过指定距离插到另一张Drawable。比如,当一个View需要一个背景比它自己还小的图片.

    • Clip Drawable

      可以在XML里面,定义一张Drawable,基于它当前的等级值用来裁剪另一张Drawable资源。相关Java类 ClipDrawable.

    • Scale Drawable

      可以在XML里面,定义一张Drawable,基于当前的等级值来改变另一张Drawable大小。相关Java类 ScaleDrawable

    • Shape Drawable

      在XML里面定义一个限定形状的几何图形包含色值、渐变等. 相关Java类 ShapeDrawable.


    注意: 在XML里面,可以把颜色值作为Drawable资源引用. 比如创建一个 state 列表drawable, 你可以给 android:drawable 设置颜色值(android:drawable="@color/green").

    1. Bitmap


    Android支持三种类型Bitmap资源: .png (优先), .jpg (可接受), .gif(不鼓励).

    你可以使用资源id直接引用图片资源.

    注意: 在编译包时,Bitmap会自动被 aapt 工具做无损压缩优化。比如,一张不需要256种颜色的真色彩的PNG可能被转换成 带颜色画板的8-bit PNG (4byte->1byte). 这样带来的好处就是图片质量一样,但空间占用变小了. 所以,我们必须认识到图片文件可能会被自动优化处理过. 如果想从图片流读取内容转化为Bitmap, 请将图片资源放到 res/raw/ 这个目录下,在这里是不会被自动优化的.

    1.1)Bitmap 文件

    Android会自动将res/drawable/  目录下的图片文件自动创建为  Drawable 类型资源.

    文件路径:

    res/drawable/filename.png (.png.jpg, 或者.gif)
    filename可以被作为资源id引用.

    Java相关的类:

     BitmapDrawable.

    资源引用方式:

    在Java: R.drawable.filename
    在XML: @[package:]drawable/filename

    示例:

    比如 res/drawable/myimage.png, 以下的布局文件会把这张图片设置到ImageView:

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

    通过以下代码,可以获取到一个 Drawable实例:

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


      1.2)XML Bitmap

      XML定义的Bitmap. 效果可以作为原始位图. 这个XML可以指定额外的属性,比如抖动(dithering)和 平铺(tiling).

      注意: 你可以使用 <bitmap> 作为 <item> 的子元素. 比如,当创建一个 state 列表或者layer 列表, 你可以用给<item>设定 android:drawable 属性,采用 <bitmap> 来设置drawable.

      • 文件路径:

      • res/drawable/filename.xml
        filename可以被作为资源id引用.

      • Java相关的类:

         BitmapDrawable.

      • 资源引用方式:

        在Java: R.drawable.filename
        在XML: @[package:]drawable/filename

      • 语法:

        <?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:tileMode=["disabled" | "clamp" | "repeat" | "mirror"] />
      • 相关元素:

      • xmlns:android

        必选. XML 命名空间, 而且必须是"http://schemas.android.com/apk/res/android". 只有根部的元素需要声明命名空间,子元素不需要.

      • android:src

        Drawable 资源必选. 指向Drawable资源.

      • android:antialias

        Boolean. 启用或关闭抗锯齿.

      • android:dither

        Boolean. 开启或关闭bitmap的抖动功能,如果图片与屏幕没有匹配的像素配置(比如:一张 ARGB 8888 图片使用在 RGB 565 的屏幕上).

      • android:filter

        Boolean. 启用或禁用位图过滤效果。当图片被拉伸或者收缩,过滤会被用来平滑图片的显示效果.

      • android:gravity

        Keyword. 定义图片的位置. 如果图片比容器小,它被用来定义图片在容器中的布局位置.

        必须是一个或多个以下常量值 (以 '|'隔开):

        常量值 描述
        top 从顶部开始渲染,不改变尺寸.
        bottom 从底部开始渲染,不改变尺寸.
        left 从左边开始渲染,不改变尺寸.
        right 从右边开始渲染,不改变尺寸.
        center_vertical 与容器垂直居中,不改变尺寸.
        fill_vertical 改变竖直的高度,从而正好布满容器(垂直方向).
        center_horizontal 与容器水平居中,不改变尺寸.
        fill_horizontal 改变水平的长度,从而正好布满容器(水平方向).
        center 水平和垂直居中,不改变尺寸
        fill 默认,改变大小,以便正好填满容器。
        clip_vertical 附件选项,可以支持裁剪顶部或者底部的图片,注意不会同时裁剪顶部和底部。具体裁剪哪一个部分,取决于是top布局还是bottom布局
        clip_horizontal 附件选项,可以支持裁剪左边或者右边的图片,注意不会同时裁剪左边和右边。具体裁剪哪一个部分,取决于left布局还是right布局
      • android:tileMode

        Keyword. 定义平铺模式. 当这个模式被开启, 图片会被重复地铺满容器。 android:gravity的设置会无效的.

        必须是以下的其中一个常量值:

        常量值 描述
        disabled 默认值,不会平铺。
        clamp 如果着色器的绘制超出了它的界限,则会复制它的边界颜色(大意就是图片太小了,其他未填满的区域则使用这张图片的边界颜色来填充)
        repeat 水平和竖直方向重复着色器的图片
        mirror 水平和竖直方向重复着色器的图片,交替镜像,这样看起来像是无缝连接
      • <bitmap>

        定义位图资源和属性.


      • 示例:

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


        一个NinePatch 的 PNG (.9.png)图片可以自动扩展/收缩. 我们一般会给一个View控件设置一个 "wrap_content"属性,这样内容可以跟着View大小的改变去自适应。这时候就可以使用9.png图片,因为它会自动缩放来满足当前 View的大小.

        和 bitmap使用方法一样 .

        2.1)Nine-Patch 文件

        • 文件路径:

          res/drawable/filename.9.png
          filename可以作为资源ID引用.

        • Java类:

           NinePatchDrawable.

        • 资源引用方式:

          在Java: R.drawable.filename
          在XML: @[package:]drawable/filename

        • 示例:

          比如 res/drawable/myninepatch.9.png, 以下是一个Button如何使用它作为背景图:

          <Button
              android:layout_height="wrap_content"
              android:layout_width="wrap_content"
              android:background="@drawable/myninepatch" />


          2.2)XML Nine-Patch

           XML Nine-Patch 是定义在 XML的Nine-Patch文件. XML可以图片设置抖动.

          • 文件路径:

            res/drawable/filename.xml
            filename 可以作为资源ID.

          • Java类:

            NinePatchDrawable.

          • 资源引用方式:

            在Java: R.drawable.filename
            在XML: @[package:]drawable/filename

          • 语法:

          • <?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"] />
          • 相关元素:

            • xmlns:android

              String必须. 命名空间,值必须是"http://schemas.android.com/apk/res/android".

            • android:src

              Drawable 资源. 必须. 指向Nine-Patch 文件.

            • android:dither

              Boolean. 开启或关闭bitmap的抖动功能,如果图片与屏幕没有匹配的像素配置(比如:一张 ARGB 8888 图片使用在 RGB 565 的屏幕上).

            • <nine-patch>

              定义 Nine-Patch 源和它的属性.


          • 示例:

          • <?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 列表


          一个 LayerDrawable 对象是一个Drawable资源,它管理着多个Drawable资源. 每一个资源时按顺序去绘制的—最后的drawable绘制在最顶层.

          每一个 <item> 元素代表一个drawable资源,都放在 <layer-list> 元素下.

          • 文件路径:

            res/drawable/filename.xml
            filename可以被作为资源引用.

          • Java类:

             LayerDrawable.

          • 资源引用方式:

            在Java: R.drawable.filename
            在XML: @[package:]drawable/filename

          • 语法:

          • <?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>
          • 相关元素:


            • android:drawable

              Drawable 资源必须. 指向Drawable资源.

            • android:id

              资源 ID. 一个代表Drawable的唯一资源标识符. 

            • android:top

              Integer. 顶部的偏移量,单位像素.

            • android:right

              Integer. 右边的偏移量,单位像素.

            • android:bottom

              Integer. 底部的偏移量,单位像素.

            • android:left

              Integer. 左边的偏移量,单位像素.

            • xmlns:android


              String必须. 命名空间,值必须是"http://schemas.android.com/apk/res/android".

            • <layer-list>

              必须. 而且必须是根部元素。 可以包含一个或多个 <item> 元素.

            • <item>

              定义一张Drawable. 必须是 <selector> 的子元素.  <bitmap> 也可以作为子元素.

              默认,所有的Drawable都会被自动缩放,以适用当前容器的大小. 因此,放置你的图片在不同的位置,可能导致View和一些图片的尺寸改变. 为了避免item的drawable尺寸出现改变,可以在 <item>放置 <bitmap>  元素来指定drawable。或者定义gravity的属性等来避免出现缩放情况,比如设置 "center". 比如,以下的 <item> 会自动缩放以适应View容器大小:

              <item android:drawable="@drawable/image" />

              为了避免缩放,我们可以使用 <bitmap> 元素,同时把gravity属性设置位center避免自动缩放:

              <item>
                <bitmap android:src="@drawable/image"
                        android:gravity="center" /><
              /item>
          • 示例:

            res/drawable/layers.xml:

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

            注意这个例子使用多个交叉的 <bitmap> 元素来定义drawable,并把gravity设置为"center" . 因为图像偏移量改变,导致View容器大小改变时,上述的做法也可以保证所有的图片都不会做缩放 .

            给View设置背景:

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

            以下是递增偏移量的多个图片叠加效果:


            4. State 列表


            一个StateListDrawable 对象代表的是多张图片资源,根据按钮的不同状态显示不同的图片. 比如一个 Button 控件可以存在多个状态(pressed, focused, 或者其它状态) 。通过使用state列表的drawable,可以为按钮的不同状态提供不同的背景图片.

            可以在XML里面描述不同的状态. 每一个 <item> 代表一个图片,作为<selector> 的子元素。每一个 <item> 使用不同的属性值来定义它会被应用于什么状态下的背景.

            在状态改变后,Android系统会从顶部往下查找,找到一个符合条件的就返回(注意:这里不是最佳查找,而是第一个满足查找).

            • 文件路径:

              res/drawable/filename.xml
              filename可以作为资源ID引用 .

            • Java类:

               StateListDrawable.

            • 资源引用:

              在 Java: R.drawable.filename
              在 XML: @[package:]drawable/filename

            • 语法:

            • <?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:drawable

                Drawable 资源必选. 指向Drawable资源.

              • android:state_pressed

                Boolean. "true" 表示View被按下 ; "false" 表示默认状态, 非按下态.

              • android:state_focused

                Boolean. "true" 表示处于输入焦点 (比如用户选中 text input); "false" 表示默认状态, 非聚焦状态.

              • android:state_hovered

                Boolean. "true" 如果光标悬停在该View上面; "false" 则相反. 一般,这个和 "focused" 使用一样的图片.

                 API level 14才支持.

              • android:state_selected

                Boolean. "true" 表示被选中状态 (比如使用d-pad导航滑动列表的时候。比如功能机,没有触屏功能); "false" 则是未被选中状态.

              • android:state_checkable

                Boolean. "true" 表示处于可勾选状态; "false" 表示不可勾选状态. (只有当对象是一个处于“可勾选”和“不可勾选”之间装换)

              • android:state_checked

                Boolean. "true" 表示处于勾选状态; "false" 表示处于非勾选状态.

              • android:state_enabled

                Boolean. "true" 表示处于启用状态 (可以接受点击/触摸); "false" 表示被禁用.

              • android:state_activated

                Boolean. "true" 表示对象被激活,可以做持续性选择(比如在持续性选择视图里面去高亮已选择的列表项); "false" 表示没有被激活.

                API level 11才开始支持.

              • android:state_window_focused

                Boolean. "true" 表示程序窗口获得焦点 (即应用在前台), "false" 表示应用程序失去焦点 (比如通知栏被拉下或是弹出对话窗口).

              • xmlns:android

                String必选. 定义了XML的命名空间, 必须是"http://schemas.android.com/apk/res/android".

              • android:constantSize

                Boolean. "true"表示状态在改变,但Drawable资源的已经大小保持常量不变 (大小是所有状态中的最大值); "false" 表示大小随着当前状态而改变. 默认false.

              • android:dither

                Boolean. "true" 表示开启图片抖动; "false"禁止图片抖动. 默认是true.

              • android:variablePadding

                Boolean. "true" 表示当前图片间距随着所选择的状态而改变; "false" 表示图片间距保持不变的情况下 (基于所有状态的最大padding). 开启这个特性,当状态改变时,需要自己实现layout布局, 通常是不被支持的. 默认是 false.

              • <selector>

                必选. 根部元素. 包含一个或多个 <item> 元素.

              • <item>

                定义了一个已知状态下的图片资源, 必须是<selector> 的子元素.


            • 示例:

              比如 res/drawable/button.xml:

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

              以下将把上述的state 列表drawable应用于Button:

              <Button
                  android:layout_height="wrap_content"
                  android:layout_width="wrap_content"
                  android:background="@drawable/button" />


             
            Android高级开发 更多文章 Android Studio 入门技巧之<基础篇> Android Studio 之<进阶篇:实用快捷键> Android Studio 之<进阶篇:IDE设置> 2015年度腾讯MIG内部技术峰会 多团队协同开发经验
            猜您喜欢 Golang语言社区--了解C++ 用libcurl库进行http通讯网络编程 从微软巨额收购 LinkedIn 看科技行业趋势 IT职涯路~想想五年后的自己 经验分享 | 如何以项目的方式进行运维管理? 创业分享4:精通你的用户