赞
踩
搞安卓有些时间了,对图片老是存在一些疑惑:给View设置背景的原理是啥?啥是Drawable呢?Bitmap又是啥呢 ?Bitmap与Drawable有啥区别呢?整天看着这些熟悉有陌生的名词,当面对这些问题时却发现自己能说出来的却很少,,,, 今天就来谈谈自己的发现。
首先用一句话来总结下Drawable吧:Drawable是对安卓中所有可绘制图像的抽象,也就是说安卓中的图像是以Drawable形式存在的。
这点就要从View展示图片的原理来验证了~ 安卓中的所有UI最终都是以View的形式展示出来的,所以可以先看下安卓的View如何展示背景的。
总结了下有如下常见两种方式:
public void setBackgroundResource(@DrawableRes int resid) {
if (resid != 0 && resid == mBackgroundResource) {
return;
}
Drawable d = null;
if (resid != 0) {
// 吧资源id代表的图片转化为Drawable对象
d = mContext.getDrawable(resid);
}
// 调用setBackground方法设置Drawable
setBackground(d);
mBackgroundResource = resid;
}
可见View#setBackgroundResource源码十分简单,吧资源id代表的图片转化为Drawable对象,然后调用自身的setBackground设置Drawable对象。
原来setBackgroundResource最终会调用setBackground鸭~ 那就继续探究呗
public void setBackground(Drawable background) { //1、调用setBackgroundDrawable setBackgroundDrawable(background); } /** * @deprecated use {@link #setBackground(Drawable)} instead */ @Deprecated public void setBackgroundDrawable(Drawable background) { ··· // 避免相同background重复设置 if (background == mBackground) { return; } ··· // 作为成员变量保存份 mBackground = background; // 2、重新绘制,走draw方法。 invalidate(true); invalidateOutline(); } public void draw(Canvas canvas) { ··· //3、走drawBackground方法 drawBackground(canvas); ··· } private void drawBackground(Canvas canvas) { // 4、取之前保存的成员变量mBackground 赋值给background final Drawable background = mBackground; if (background == null) { return; } ··· if ((scrollX | scrollY) == 0) { // 5、使用Drawable#draw 在canvas上渲染 background.draw(canvas); } else { canvas.translate(scrollX, scrollY); // 5、使用Drawable#draw 在canvas上渲染 background.draw(canvas); canvas.translate(-scrollX, -scrollY); } }
可见给View设置一个背景图,背景图首先会被转化为Drawable,最终调用Drawable#draw吧drawable渲染在画布上。
前面说了“Drawable是对安卓中所有可绘制图像的抽象” 那么Drawable既然是一个抽象定义那么他有哪些实现呢?
Drawable是可以绘制的东西,常见的xml如布局、矢量图像、普通图片等等都是属于Drawable的范畴,接下来康康安卓中Drawable有哪些常见的具体的实现:
安卓中提供了好多Drawable的具体实现类,在开发中我们或许最常见的就是碰到过ShapeDrawable、BitmapDrawable:
如上ShapeDrawable我们通常使用xml来进行实现,然后作为bg设置给View,如下这个以shape为根节点的xml文件作为bg设置给view时,xml文件就会被转化为ShapeDrawable对象。
BitmapDrawable 也是最常见的,当安卓的图片以View为载体展示时就会被转化为BitmapDrawable对象,然后被渲染到Canvas上。如直接给吧图片作为背景设置给View。
有时候需要在代码中获得BitmapDrawable 对象还可以这样做:
//R.drawable.my_image 一张具体的图片
val myImage: Drawable = ResourcesCompat.getDrawable(context.resources, R.drawable.my_image, null)
其他的就不多谈了后续会专门总结下各种Drawable~
Bitmap存储的是像素点,代表具体的一张图片信息。安卓中对图片的裁剪、缩放等一系列的操作需要把图片文件以Bitmap的形式加载到内存中进行操作。
Bitmap和Drawable也是有联系的,安卓通过View展示一张具体的图片时会把Bitmap转化为BitmapDrawable,然后View通过Canvas来渲染BitmapDrawable到画布上。
安卓中操作图片需要使用到Bitmap相关的api,这里可以先了解下~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。