Potato
Potato copied to clipboard
Android:Drawable 和 Bitmap
Android:Drawable 和 Bitmap
[TOC]
这篇文章简单介绍下不同的 Drawable 和 Bitmap 的关系,以及各种的 Drawable。
Drawable
其中 Drawable 的注释如下:
A Drawable is a general abstraction for "something that can be drawn." Most often you will deal with Drawable as the type of resource retrieved for drawing things to the screen; the Drawable class provides a generic API for dealing with an underlying visual resource that may take a variety of forms. Unlike a
View
, a Drawable does not have any facility to receive events or otherwise interact with the user.
public abstract class Drawable {
......
}
这里看到 Drawable 只是一个抽象概念, 表示"something that can be drawn".
下面紧接着有一段话:
Though usually not visible to the application, Drawables may take a variety of forms:
- Bitmap: the simplest Drawable, a PNG or JPEG image.
- Nine Patch: an extension to the PNG format allows it to specify information about how to stretch it and place things inside of it.
- Vector: a drawable defined in an XML file as a set of points, lines, and curves along with its associated color information. This type of drawable can be scaled without loss of display quality.
- Shape: contains simple drawing commands instead of a raw bitmap, allowing it to resize better in some cases.
- Layers: a compound drawable, which draws multiple underlying drawables on top of each other.
- States: a compound drawable that selects one of a set of drawables based on its state.
- Levels: a compound drawable that selects one of a set of drawables based on its level.
- Scale: a compound drawable with a single child drawable, whose overall size is modified based on the current level.
**Drawable 是一个抽象的概念, 而 Bitmap 是其存在的实体之一. **
Bitmap
类的定义如下:
public final class Bitmap implements Parcelable {
...
}
没有实现 Drawable, 而是通过 BitmapDrawable 将两者联系起来。
public class BitmapDrawable extends Drawable {
...
}
在 Drawable 类中有一个方法:
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);
}
通过 Bitmap 的构造函数,可以将 Bitmap 转换为 Drawable。
在 BitmapDrawable 中同样可以得到 Bitmap 对象:
public final Bitmap getBitmap() {
return mBitmapState.mBitmap;
}
简单来说:
可以简单地理解为 Bitmap 储存的是 像素信息,Drawable 储存的是 对 Canvas 的一系列操作。
而 BitmapDrawable 储存的是「把 Bitmap 渲染到 Canvas 上」
这个操作。
各种 Drawable
android内置了如下几种Drawable类型:ColorDrawable、GradientDrawable、BitmapDrawable、 NinePatchDrawable、InsetDrawable、ClipDrawable、ScaleDrawable、 RotateDrawable、AnimationDrawable、LayerDrawable、LevelListDrawable、 StateListDrawable、TransitionDrawable ShapeDrawable。 Android把可绘制的对象抽象为Drawable,不同的图形图像资源就代表着不同的drawable类型。Android FrameWork提供了一些具体的Drawable实现,通常在代码中都不会直接接触Drawable的实现类。
ColorDrawable
ColorDrawable通常设置在colors.xml文件中,比如设置View背景为纯色,实际设置的就是ColorDrawable.
public void setBackgroundColor(@ColorInt int color) {
if (mBackground instanceof ColorDrawable) {
((ColorDrawable) mBackground.mutate()).setColor(color);
computeOpaqueFlags();
mBackgroundResource = 0;
} else {
setBackground(new ColorDrawable(color));
}
}
颜色可绘制类。类构造时指定一个颜色,或者调用setColor指定颜色,setAlpha函数会把设置的透明度和本来的颜色的透明度相乘。这个可绘制类用来实现简单的单颜色的绘制。
GradientDrawable
GradientDrawable通常用来设置渐变色。写在XML文件中通常和shape结合使用
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#FFF"
android:endColor="#000"
android:angle="45" />
</shape>
BitmapDrawable 位图可绘制类
位图可绘制类。在构造时指定一个Bitmap对象或者一个位图文件。位图显示时需要指定:像素和设备尺寸的映射,显示的位置,显示模式三种属性。
因为位图里面的像素是一个抽象的概念他没有具体的物理尺寸,而设备的像素则是物理的,他有大小。因此需要有一个方法来指定位图像素转化为物理像素的映射关系,这样位图的像素才可以真正的显示在设备上。下面就是提供的三种映射设置方法:
//画布上的密度比值
public void setTargetDensity(Canvas canvas)
//当前屏幕的密度比值
public void setTargetDensity(DisplayMetrics metrics)
//指定密度比值,注意这里的密度是DisplayMetrics中的DENSITY_XXX。
public void setTargetDensity(int density)
系统会根据密度公式:** 位图尺寸 * density / 屏幕的密度 ** 来将位图显示在具体的设备上。
你需要为位图指定绘制到画布上的位置以及缩放到区域的方式:
//这里的android.view.Gravity参考值。比如显示在左上角,比如拉伸显示在整个画布中等等
public void setGravity(int gravity)
ClipDrawable 裁剪可绘制类
这个是一个Drawable的修饰派生类,构造函数是对某个Drawable对象进行裁剪显示。裁剪的范围设置通过setLevel来设置,0为全部不显示,10000为全部显示,设置了范围之后还需要设置裁剪的方向和从什么地方开始裁剪,参考构造函数:
public ClipDrawable(Drawable drawable, int gravity, int orientation)
ClipDrawable主要的应用场景是让某个Drawable逐渐进行展开或者收缩显示,而这都是通过调用setLevel方法来完成的。
AnimationDrawable 帧动画可绘制类
这是一个容器可绘制类,用于定期播放一批指定的Drawable。不可以和ClipDrawable结合起来播放逐渐展开的动画。这个类里面的一个Drawable对象就是一帧。下面的一系列方法分别用来管理这些帧动画:
public void addFrame(Drawable frame, int duration) //添加要播放的Drawable帧以及播放时长。
public int getDuration(int i) //每帧时长
public Drawable getFrame(int index) //获取帧
public int getNumberOfFrames() //得到总帧数
public void setOneShot(boolean oneShot) //单次还是循环
InsetDrawable缩进可绘制类
这个是一个容器类。实现容器内Drawable四个方向缩进或者某个方向的缩进。如果为负数则是外缩进,这个类也可以实现缩放的功能,注意这里不是裁剪,而是会有缩放效果。
ScaleDrawable 缩放可绘制类
这个一个容器类,可以用来缩放另外一个Drawable对象。你可以在构造中指定缩放的比例和缩放的中心点,注意的是所缩放的Drawable对象的level不能为0.
RotateDrawable 旋转可绘制类
这个可绘制类不支持代码建立,只支持XML文件构造。可以指定开始角度,结束角度,旋转的中心点。 最后可以通过setLevel来控制从开始到结束的角度中间的过程。下面是一个XML来设置旋转可绘制类的方法.
ShapeDrawable 形状可绘制类。
用于建立各种形状。对于形状的边线来说可以通过如下方法来获取一个Paint对象并设置画笔和阴影效果.
PaintDrawable 圆角矩形可绘制类。
这个类是ShapeDrawable的派生类。是圆角矩形RoundRectShape的简化版本,只会设置外圆角,只需要设置一个或者8个即可。一般用这个类来设置圆角按钮背景。
LayerDrawable 图层可绘制类。
用于重叠多个可绘制对象。这是一个容器可绘制类,里面可以添加多个子可绘制对象,每个子可绘制对象就是其中的一层。
TransitionDrawable 淡入淡出可绘制类
这个类是LayerDrawable的子类,可以实现动画效果。这个类只支持2个子可绘制对象,所展示的效果是第0层慢慢变淡消失,第一层慢慢清楚显示。
NinePatchDrawable .9格式的可绘制类
.9格式的可绘制类,一般用于那些需要特定区域拉伸显示的场景,比如气泡对话框。.9格式的图片一般用png文件来实现。
GradientDrawable 渐变的可绘制类。
渐变可绘制类提供了一种多颜色过渡显示效果的可绘制类。根据颜色过渡的方式系统默认提供的渐变有线性渐变(LINEAR_GRADIENT),放射渐变(RADIAL_GRADIENT),**旋转扫描渐变(SWEEP_GRADIENT)**三种类型。你可以通过如下方法来设置可绘制对象的渐变类型: