Drawable与Bitmap

Drawable与Bitmap

1.什么是Drawable

Android中的Drawable(可绘制对象) 表示“可以绘制的东西”,是一个抽象类,是所有Drawable对象的基类。最常见的颜色和图片都可以是一个Drawable. 与View不同,可绘制对象不能接收事件,也不能与用户进行交互。

2.Drawable的子类/类型

2.1位图文件

位图图形文件(.png.jpg.gif)。创建 BitmapDrawable

BitmapDrawable表示一张图片,是一个包裹了位图(bitmap)的Drawable,可以平铺,拉伸或对齐。 可以从文件路径,输入流,inflate .xml, 从Bitmap对象创建BitmapDrawable对象。

  1. 引用drawable文件夹下的图片时,系统实际是为这张图片创建了BitmapDrawable对象

  2. 可以使用元素在XML文件中定义它,并R.drawable.filename来引用。

    比如bitmap_xml.xml和touxiang.png(200*200 PNG)存储在drawable文件夹下,文件的内容为

    
    
    <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
        android:antialias="true"
        android:dither="true"
        android:filter="true"
        android:gravity="center"
        android:src="@drawable/touxiang"
        android:tileMode="mirror">
    bitmap>

    然后在ImageView中像引用一张图片那样去使用

    <<ImageView
            android:id="@+id/imageView2"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/bitmap_xml"
            app:srcCompat="@drawable/bitmap_xml" />

    效果是这样的:

    image-20200618223410222

2.2九宫格文件与NinePatchDrawable

具有可伸缩区域的 PNG 文件,支持根据内容调整图像大小 (.9.png)。创建 。

2.3图层列表

管理其他可绘制对象阵列的可绘制对象。这些可绘制对象按阵列顺序绘制,因此索引最大的元素绘制于顶部。创建 LayerDrawable

2.4状态列表与StateListDrawable

此 XML 文件用于为不同状态引用不同位图图形(例如,按下按钮时使用不同图像)。

StateListDrawable对应于标签,表示Drawable的集合,每个drawable对应View的一种状态,系统会根据View的状态选择合适的Drawable,主要用于设置可单击的View的背景(background属性),最常见的是Button.

示例:button_background.xml


<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/btn_pressed"/>
    <item android:state_focused="true" android:drawable="@drawable/btn_focused"/>
    <item android:drawable="@drawable/btn_normal"/>
selector>

一个item对应一个具体的Drawable,系统按照从上到小的顺序查找,找到第一个匹配的就停止。一般来说,默认的item放在selector的最后一条且不附带任何状态,因为默认的item不附带任何状态,所以它可以匹配View的任何状态.

2.5级别列表

此 XML 文件用于定义管理大量备选可绘制对象的可绘制对象,每个可绘制对象都配有最大备选数量。创建 LevelListDrawable

2.6转换可绘制对象

此 XML 文件用于定义可在两种可绘制对象资源之间交错淡出的可绘制对象。创建 TransitionDrawable

2.7插入可绘制对象

此 XML 文件用于定义以指定距离插入其他可绘制对象的可绘制对象。当视图需要小于视图实际边界的背景可绘制对象时,此类可绘制对象非常有用。

2.8裁剪可绘制对象

此 XML 文件用于定义对其他可绘制对象进行裁剪(根据其当前级别值)的可绘制对象。创建 ClipDrawable

2.9缩放可绘制对象

此 XML 文件用于定义更改其他可绘制对象大小(根据其当前级别值)的可绘制对象。创建 ScaleDrawable

2.9形状可绘制对象与 GradientDrawable

此 XML 文件用于定义几何形状(包括颜色和渐变)。 GradientDrawable和ShapeDrawable对象都可以从xml文件中获得,且根标签都必须是,GradientDrawable支持渐变色,这俩可以理解为通过颜色来构造图形。

实际创建的是GradientDrawable对象

用法示例:XML文件保存在 res/drawable/gradient_box.xml 中:


<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <gradient
        android:startColor="#FFFF0000"
        android:endColor="#80FF00FF"
        android:angle="45"/>
    <padding android:left="7dp"
        android:top="7dp"
        android:right="7dp"
        android:bottom="7dp" />
    <corners android:radius="8dp" />
shape>

此布局 XML 会将形状可绘制对象应用到视图:

<<TextView
    android:background="@drawable/gradient_box"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content" />

代码中使用

Resources res = getResources();
Drawable shape = ResourcesCompat.getDrawable(res, R.drawable.gradient_box, getTheme());

TextView tv = (TextView)findViewById(R.id.textview);
tv.setBackground(shape);

各属性详细的解释参考https://developer.android.google.cn/guide/topics/resources/drawable-resource#corners-element

3.位图

位图图像。Android 支持以下三种格式的位图文件:.png(首选)、.jpg(可接受)、.gif(不建议)。

您可以使用文件名作为资源 ID 直接引用位图文件,也可以在 XML 中创建别名资源 ID。

:在构建过程中,可通过 aapt 工具自动优化位图文件,对图像进行无损压缩。例如,不需要超过 256 色的真彩色 PNG 可通过调色板转换为 8 位 PNG。这样产生的图像质量相同,但所需内存更少。因此请注意,此目录中的图像二进制文件在构建时可能会发生变化。如果您打算以比特流的形式读取图像,进而将其转换为位图,请改为将图像放在 res/raw/ 文件夹中,避免系统对其进行优化。

位图文件

.png.jpg.gif都是位图 文件。将一个位图文件保存到 res/drawable/ 目录中时,Android系统 会为其创建一个指向BitmapDrawable 资源的指针。

  • 文件位置:

    res/drawable/*filename*.png.png.jpg.gif) 文件名用作资源 ID。

  • 资源引用:

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

  • 示例:

    当图像保存为 res/drawable/myimage.png 后,此布局 XML 会将该图像应用至ImageView

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

    以下应用代码将通过资源id来获得图像的Drawable对象:

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

系统是如何加载一张图片的?

​ Bitmap在Android系统中表示一张图片,可以是png jpg 或gif . BitmapFactory类提供了4类方法:decodeFile,decodeResouce,decodeStream,和decodeByteArray,分别用于从文件,资源,输入流,以及字节数组中加载出一个Bitmap。其中decodeFile,decodeResouce又间接调用了decodeStream方法,这四类方法最终是在Android底层实现的,对应着BitmapFactory类的几个Native方法。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!