Drawable Mutations--绘图变异

翻译 2012年03月24日 21:49:32

原文连接:点击打开链接

        Android提供的Drawable对构建应用程序极为有用。Drawable是一个与View相关的可插入式绘图容器。如:BitmapDrawable用于图片显示,ShapeDrawable用来绘制蒙板和渐变图,等等。通过组合使用则可以创建更为复杂的渲染效果。

    Drawables允许用来方便的定制Widget,而毋需继承它。事实上,由于Drawables如此的方便,以至大量默认的Android应用程序和Widget都是用它构建的;Android的核心框架中,大约用了700个Drawables。由于Android系统中Drawables使用如此之广泛,因此,Android从资源中加载它们时也进行了优化。例如,每次创建一个Button时,一个新的Drawable就从框架资源文件(android.R.drawable.btn_default)中被加载。这就意味着:所有应用中的所有Buttons使用不同的Drawables实例作为它们的背景图案。但是,所有这些Drawables共享一个通用状态:“constant state(常态)”。状态内容根据所用drawable的类型而变,但通常包含了资源文件可定义的所有属性。

Button为例,常态时包含了一幅位图,这样的话,所有应用中的所有buttons共享这幅位图,节省了很多空间。

        下面的框图显示了当你将同一幅图指定给两个不同的View作背景时哪些实体被创建了。如你所见,两个drawables被创建了,但它们共享同一个常态和同一幅图:


这种状态共享特性在避免浪费内存的同时,也给修改drawable属性带来了问题。设想有一个用到图书列表的应用程序。每本书名旁边都有一颗星,当星标记为完全不透明时,表示喜爱;标记为半透明的时,表示不喜爱。为达到这个效果,你很可能在你的list adapter's getView()方法中这样写代码:

Book book = ...;
TextView listItem = ...;

listItem.setText(book.getTitle());

Drawable star = context.getResources().getDrawable(R.drawable.star);
if (book.isFavorite()) {
  star.setAlpha(255); // opaque
} else {
  star.setAlpha(70); // translucent
}
不幸的是,这段代码会产生一个相当奇怪的结果:所有的drawables都具有同样的透明度:


这种结果就可以用“constant state”来解释了。尽管我们在每个列表项中都获得了一个新的drawable实例,但“constant state”和BitmapDrawable仍然是共享的,而透明度是“constant state”的一部分。因此,改变一个drawable实例的透明度,就会改变其它多有drawable实例的透明度。更糟糕的是,在Android早期版本1.0和1.1中解决此类问题是很难的。

      Android 1.5及其之后的版本通过提供一个新的方法:mutate(),就很容易的解决了这个问题。当你在drawable中使用该方法时,drawable的“constant state”被复制了,这样就允许你在不影响其它drawable属性的情况下修改你想要修改的drawable的任何属性。注意:即使对drawable进行了变异处理,位图仍然是共享的。下面这幅框图展示了drawable上使用mutate()方法后发生了哪些变化:


使用mutate( )修改前面的代码片段:

Drawable star = context.getResources().getDrawable(R.drawable.star);
if (book.isFavorite()) {
  star.mutate().setAlpha(255); // opaque
} else {
  star. mutate().setAlpha(70); // translucent
}
为了方便,mutate( )返回的是drawable自身,这样可以进行链式的方法调用,而并未创建新的drawable实例。使用新的代码片段后,应用程序现在可以正常工作了:


博主注:所译内容,已经经过代码验证,情况确实如上所述。



Drawable Mutations

Android 的Drawable在应用程序开发中使用的非常广泛.我们可以把Drawable看作一个可插拔的绘图容器,这个容器通常与一个View相关联.例如,一个BitmapDrawable 通常被用...

android ---Drawable Mutations笔记

原文来自Android SDK文档中的 resources/articles/drawable-mutations.html 在Android中有大量的图片加载,Android性能优化其加载过程,也...

Android开发学习之路--Drawable mutations

时间过得很快,明天终于可以拿到房子了,交完这次房租,也可以成为房东了,看看博客也好久没有更新了,最近一直在整机器人,也没有太多时间整理博客。   今天下午和同事一起遇到了一个问题,就是明明没有改变一...

Quartz-2D绘图之路径(Paths)详解

在上篇文章中,我们简单的理解了绘图上下文,今天我们来认识一下Quartz-2D中另一个重要的概念,路径(Paths)。 一、理解路径   路径定义了一个或多个形状,或是子路径。一个子路径可...

Quartz-2D绘图之图形上下文详解

这篇文章就先讲讲图形上下文(Graphics Context)的具体操作。   所谓Graphics Context,其实就是表示了一个绘制目标,也就是你打算绘制的地方,它包含绘制系统用于完成绘...

ios- 绘图

创建新的类,继承于UIView 在view上添加头文件 只需要在自己新创建的view上绘图 图片绘制:将图片直接绘制倒view上 UIImage* image = [UIImage...

IOS - 绘图

创建新的类,继承于UIView 在view上添加头文件 只需要在自己新创建的view上绘图 图片绘制:将图片直接绘制倒view上 UIImage* image = [UIImage ima...

小强学Python+OpenCV之-1.3绘图

学习一下OpenCV中几个绘图函数: 1. cv2.line 2. cv2.rectangle 3. cv2.circle

iOS开发封装篇-利用CAShapeLayer和绘图封装一个动画按钮

最近在研究Quartz Core框架,重点学习了CAPlayer(图层)。今天就利用CAShapeLayer封装一个动画按钮。...
  • Cehae
  • Cehae
  • 2016年09月24日 18:34
  • 693
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Drawable Mutations--绘图变异
举报原因:
原因补充:

(最多只允许输入30个字)