### Android中的drawable和bitmap ###
- 前言
- Android 系统提供了ImageView显示普通的静态图片,也提供了AnimationDrawable 来开发逐帧动画,还可通过Animation 对普通图片使用补间动画。
- 图片不仅可以使用ImageView 来显示,也可作为Button 、Window 的背景。从广义的角度来看, Android 应用中的图片不仅包括*.png 、*.jpg、*.gif 等各种格式的位图, 也包括使用XML 资源文件定义的各种Drawable 对象。
- 为Android 应用增加了Drawable资源之后,Android SDK 会为这份资源在R 清单文件中创建一个索引项: `R.drawable. file name `。
- 接下来既可在XML 资源文件中通过@drawable/file_name 访问该Drawable 对象, 也可在Java 代码中通过`R.drawable.file name `访问该Drawable 对象。需要指出的是,R.drawable.file name 是一个int 类型的常量,它只代表Drawable对象的ID,如果Java 程序中需要获取实际的Drawable对象,则可调用Resources 的getDrawable(int id)方法来实现。当然如果ImageView使用drawable来显示,可以通过getDrawable()来获取显示的drawable
- drawable( android.graphics.drawable.Drawable )
- drawable是一个抽象的概念,凡是可以被画出来的东西都称之为drawable。[官网介绍](https://developer.android.com/reference/android/graphics/drawable/Drawable.html)drawable不可见,Drawables采取了多种形式呈现在我们面前,比如
- Bitmap: 位图----最简单的Drawable, PNG or JPEG图片。
- Nine Patch: 9patch图----可以局部缩放,定义文本区域的.9patch图片
- Vector:矢量---在XML文件中定义的一个drawable作为一组点,线和曲线及其关联的颜色信息。可以缩放这种类型的可绘制,而不会损失显示质量。
- Shape: 形状:包含简单的绘图命令而不是原始位图,允许它在某些情况下更好地调整大小。
- Layers: 层:一个复合的drawable,它可以在彼此之上绘制多个底层的drawable。
- States: 状态:根据其状态选择一组可绘图之一的复合绘图。
- Levels: 级别:根据其级别选择一组可绘图之一的复合绘图。
- Scale: 比例:一个单个可抽出的单个可抽取的组合,其总体大小根据当前级别进行修改。
- Drawable 是一个抽象的概念, 而 Bitmap 是其存在的实体之一。可以简单地理解为 Bitmap 储存的是 像素信息,Drawable 储存的是 对 Canvas 的一系列操作。而 BitmapDrawable 储存的是「把 Bitmap 渲染到 Canvas 上」这个操作。
- Drawable一般都是通过xml文件来定义,当然也可以通过代码来创建具体的Drawable对象,getResource().getDrawable()即可。只是用代码创建稍显复杂。
- Drawable的的内部宽/高(固有宽高)这个参数很重要,通过getIntrinsicHeight()和getIntrinsicWidth()获得(如果没有固有宽高,默认是-1,比如颜色构成的drawable,当然不同的子类返回的值也是不一样),但是不是所有的Drawable都有内部宽/高,比如一个颜色所形成的Drawable就没有这个概念,而且Drawable的宽高概念并不等同于它的大小,一般来说Drawable没有大小的概念,当被用作View的背景是,Drawable会被拉伸至view的同等大小
-
- 自定义drawable(使用场景还是比较少,但是某些情况,还最合适)
- 一般没有必要自定义Drawable,因为自定义drawable无法在xml文件中使用,这就降低了自定义drawable的使用范畴,但是某些情况可以使用。自定义方式和view差不多,但是没有那么复杂,它是轻量级的,比如想写一个圆形的drawable,但是通过xml来写一个圆形的drawable是很困难的, 并不是说不好写,而是,如果一个view的尺寸忽大忽小,是变化的,那么有些时候这个圆形就会被拉伸或者压扁变成椭圆,但是如果自定义来绘制一个圆形的drawable作为view的背景时,它的半径是可以随着view变化而变化的
- 一般只需要重写void draw (Canvas canvas)方法,而且从Android7.0开始,自定义drawable可以用于XML形式,官网介绍[这里](https://developer.android.com/reference/android/graphics/drawable/Drawable.html#draw(android.graphics.Canvas)%EF%BC%8C), 可以以多种方式在XML中使用自定义可绘制类drawable:
- 使用完全限定类名作为XML元素名称。对于此方法,自定义drawable类必须是公共顶级类。
- ![](http://i.imgur.com/ETCKoUB.png)
- 使用drawable作为XML元素名称,并从类属性中指定完全限定的类名。此方法可用于公共顶层类和公共静态内部类。
- ![](http://i.imgur.com/aJsvcr0.png)
- 一个颜色资源,也可以用作XML的可绘制。`android:drawable="@color/green"`
- drawable的层次结构(关于drawable的几个子类常用可以参考Android开发艺术探讨第六章,也可以参考[视频讲解](http://edu.csdn.net/course/detail/1923/29836?auto_start=1))
- [大图请点击这里](http://i.imgur.com/jo62b5Q.png)
- ![](http://i.imgur.com/jo62b5Q.png)
- Android种支持的图片格式
- PNG----推荐
- JPG----可接受的
- GIF----支持但是不推荐
- 当需要一个图片资源作为drawable,可以如下图
- ![](http://i.imgur.com/P9PDEqT.png)
- Bitmap
- 称作位图,一般位图的文件格式后缀为bmp,当然编码器也有很多如RGB565、RGB888。作为一种逐像素的显示对象执行效率高,但是缺点也很明显存储效率低。我们理解为一种存储对象比较好。
- aapt在构建过程中,位图文件可以通过工具进行无损图像压缩来自动优化。例如,不需要256色以上的真彩色PNG可以使用调色板转换为8位PNG。这将导致质量相同的图像,但需要更少的内存。因此,请注意,放置在此目录中的图像二进制文件可能在构建期间发生更改。如果您打算将图像作为位流读取,以便将其转换为位图,请将图像放在res/raw/文件夹中,而不是将其优化,也就是放在mipmap或者drawable文件夹下的位图会被优化。
- 层次结构([大图点击这里](http://i.imgur.com/2ap9PGQ.png))
- ![](http://i.imgur.com/2ap9PGQ.png)
- 大部分时候,我们只要把图片放在`/res/drawable/`目录下,就可以在程序中通过该图片对应的资源、ID 来获取封装该图片的Drawable对象。但由于手机系统的内存比较小,如果系统不停地去解析、创建Bitmap 对象, 可能由于前面创建Bitmap 所占用的内存还没有回收, 而导致程序运行时引发OutOfMemory 错误。所以Android 为Bitmap 提供了上面两个方法`boolean isRecycled()`和`void recycle()`来判断它是否已回收,以及强制Bitmap回收自己。
- Bitmap是Drawable,Drawable不一定是Bitmap .就像拇指是指头,但不是所有的指头都是拇指一样
- ![](http://i.imgur.com/Q6xKOJi.png)
- Drawable在内存占用和绘制速度这两个非常关键的点上胜过Bitmap
- 总结
- Bitmap是用来显示的实际数据,它在概念上隶属于Drawable,但是与Drawable之间不是继承关系。
- Bitmap继承Parcelable,是一个可以跨进程传输的对象,BitmapDrawable继承Drawable,可Drawable只是一个抽象类,此类是一个存放数据流的载体。
- Bitmap 并没有实现 Drawable,二者如何联系呢?
- BitmapDrawable
- public class BitmapDrawable extends Drawable {......}
- Drawable 类中有一个私有的静态方法drawableFromBitmap():
~~~
private static Drawable drawableFromBitmap(Resources res, Bitmap bm, byte[] np,
Rect pad, Rect layoutBounds, String srcName) {
if (np != null) {
return new NinePatchDrawable(res, bm, np, pad, layoutBounds, srcName);
}
return new BitmapDrawable(res, bm);
}
~~~
* * * * *
- 通过 BitmapDrawable 的构造函数,使得 Bitmap 可以转换为 Drawable。同理: BitmapDrawable 的 getBitmap 方法也会返回 bitmap对象:
~~~
public final Bitmap getBitmap() {
return mBitmapState.mBitmap;
}
~~~
- Bitmap - 称作位图,一般位图的文件格式后缀为bmp,当然编码器也有很多如RGB565、RGB888。作为一种逐像素的显示对象执行效率高,但是缺点也很明显存储效率低。我们理解为一种存储对象比较好。
- Drawable - 作为Android平下通用的图形对象,它可以装载常用格式的图像,比如GIF、PNG、JPG,当然也支持BMP,当然还提供一些高级的可视化对象,比如渐变、图形等。
- Canvas - 名为画布,我们可以看作是一种处理过程,使用各种方法来管理Bitmap、GL或者Path路径,同时它可以配合Matrix矩阵类给图像做旋转、缩放等操作,同时Canvas类还提供了裁剪、选取等操作。
- Paint - 我们可以把它看做一个画图工具,比如画笔、画刷。他管理了每个画图工具的字体、颜色、样式。
- 参考链接
- [Android中Bitmap和Drawable ](http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2013/0605/1333.html)
- [Bitmap和Drawable的区别,为什么要用bitmap?](https://www.zhihu.com/question/29561539)
- [Android中Drawable Bitmap Canvas Paint之间区别 ](http://www.cnblogs.com/playing/archive/2011/05/10/2042241.html)
- [Android 中 Bitmap 和 Drawable 相互转换的方法](http://blog.csdn.net/l_lhc/article/details/50923372)
- [Android中Bitmap和Drawable ](http://dyh7077063.iteye.com/blog/970672)
- [简单谈谈Resource,Drawable和Bitmap之间的转换 ](http://www.cnblogs.com/rayray/p/3429708.html)
- [Android Drawable Resource学习(二)、BitmapDrawable和Bitmap ](http://blog.csdn.net/lonelyroamer/article/details/8147542)
- [Bitmap类用法 详细说明](http://blog.csdn.net/ymangu666/article/details/37729109)
- [Android图像处理之Bitmap类](http://www.open-open.com/lib/view/open1333418945202.html)
- [Android Bitmap深入介绍(一)---基础](http://blog.csdn.net/xxxzhi/article/details/51607765)
- [android Bitmap.Config的用法介绍](http://wangxuefang.iteye.com/blog/1955910)
- [Android Bitmap 全面解析](http://blog.csdn.net/kinglearnjava/article/details/44676351)
- BitmapFactory
- 创造bitmap,通过解码文件、流、字节数组等,BitmapFactory 是一个工具类,它提供大量的方法,这些方法可用于从不同的数据源来解析、创建Bitmap 对象。
- 结构层次图([大图点击这里](http://i.imgur.com/Ucf3OXT.png))
- ![](http://i.imgur.com/Ucf3OXT.png)
- 前言
- Android系统的体系结构
- Dalvik VM 和 JVM 的比较
- Android 打包应用程序并安装的过程
- Android ADB工具
- Android应用开发
- Android UI相关知识总结
- Android 中window 、view、 Activity的关系
- Android应用界面
- Android中的drawable和bitmap
- AndroidUI组件adapterView及其子类和Adapter的关系
- Android四大组件
- Android 数据存储
- SharedPreference
- Android应用的资源
- 数组资源
- 使用Drawable资源
- Material Design
- Android 进程和线程
- 进程
- 线程
- Android Application类的介绍
- 意图(Intent)
- Intent 和 Intent 过滤器(Google官网介绍)
- Android中关于任务栈的总结
- 任务和返回栈(官网译文)
- 总结
- Android应用安全现状与解决方案
- Android 安全开发
- HTTPS
- 安卓 代码混淆与打包
- 动态注入技术(hook技术)
- 一、什么是hook技术
- 二、常用的Hook 工具
- Xposed源码剖析——概述
- Xposed源码剖析——app_process作用详解
- Xposed源码剖析——Xposed初始化
- Xposed源码剖析——hook具体实现
- 无需Root也能Hook?——Depoxsed框架演示
- 三、HookAndroid应用
- 四、Hook原生应用程序
- 五、Hook 检测/修复
- Android 应用的逆向与加固保护技术
- OpenCV在Android中的开发
- Android高级开发进阶
- 高级UI
- UI绘制流程及原理
- Android新布局ConstraintLayout约束布局
- 关键帧动画
- 帧动画共享元素变换
- Android异步消息处理机制完全解析,带你从源码的角度彻底理解
- Android中为什么主线程不会因为Looper.loop()里的死循环卡死?
- 为什么 Android 要采用 Binder 作为 IPC 机制?
- JVM 中一个线程的 Java 栈和寄存器中分别放的是什么?
- Android源码的Binder权限是如何控制?
- 如何详解 Activity 的生命周期?
- 为什么Android的Handler采用管道而不使用Binder?
- ThreadLocal,你真的懂了吗?
- Android屏幕刷新机制