`
410063005
  • 浏览: 179991 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

(翻译) Android SDK文档之Drawable Mutations

 
阅读更多

原文来自Android SDK文档中的 resources/articles/drawable-mutations.html

       

       Android的drawables非常便于构建应用。Drawable是一个可插拨的绘制容器(drawing container), 通常与一个View关联。 比如, BitmapDrawable用于显示图片, ShapeDrawable用于绘制图形和渐变, 等等。 还可以组合使用,创建更复杂的渲染效果。

 
       Drawables允许不必继承Widget就可以方便地定制Widget的渲染效果。事实上, 它们是如此方便易用,多数自带的Android应用和Widget是通过使用Drawables来构建的。 Android核心框架使用了大约700个Drawables。 由于Drawables的系统中大量使用, Android优化过其加载过程。  比如, 每次当你创建一个Button, 一个新的Drawable将从框架资源文件中(android.R.drawable.btn_default)加载进来。 这意味着所有应用中所有的button使用不同的Drawable实例作为它们的背景。 但是所有这些Drawables共享相同的状态, 即Constant State。 这个状态中的内容因使用的Drawable类型而变化,但通常都包含所有可用的资源属性。 以button为例, Constant State包含一个Bitmap Image。 这样,所有应用中的所有Button都共享相同的Bitmap, 可以节省大量内存。
 
     下图展示当把同一个Image资源作为两个不同的View的背景时哪些实体将被创建。 正如你所见, 两个Drawable被创建,但他们共享同一个Constant State, 即同一个Bitmap
      虽然共享Constant State这个特性有利于减少内存的使用, 但当你需要修改Drawable的属性时可能产生问题。 考虑一个应用, 它有一个Book列表。 每个Book书名旁边有一个星形, 当用户标记当前Book为喜欢时这个星形完全不透明, 而未标记为喜欢时这个星形为半透明。 为实现这个显示效果, list adapter中的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
}
很不幸, 以上代码将产生奇怪的结果:所有的星形都成了半透明。如下图所示:
       这个结果也说明了Constant State的特点。 尽管我们为每个Item生成了一个新的Drawable实例, Constant State仍然是相同的。 对BitmapDrawable而言, 透明度也是Constant State的一部分。因此, 改变一个Drawable实例的透明度, 同时也会影响其他Drawable实例的透明度。 更糟糕的是, 这个问题在Android 1.0和Android 1.1上不容易修复。
 
      Android 1.5及以上版本提供了一个简单的办法来解决这个问题:新添加的mutate()方法。当你在某个Drawable上调用mutate()方法时, 将复制该Drawable的Constant State, 并允许修改该复制结果的属性且不会对其他Drawable生成影响。 注意, 就算复制了Drawable, Drawable仍然共享Bitmap。 下图显示了在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实例 。 修改后的代码结果是正确的。 
 
(另外附上自己根据这篇文档写的一个例子, 验证下mutate()的用法)
代码:
public class ConstantStateActivity extends ListActivity {

	private ListAdapter mAdapter;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mAdapter = new MyListAdapter(this, R.layout.my_adatper, R.id.textView1, Arrays.asList("and-aa", "iphone-b"));
		getListView().setAdapter(mAdapter);
	}
	
	static class MyListAdapter extends ArrayAdapter<String> {
		private int mRes;
		private List<String> mData;
		
		public MyListAdapter(Context context, int resource,
				int textViewResourceId, List<String> objects) {
			super(context, resource, textViewResourceId, objects);
			this.mRes = resource;
			this.mData = objects;
		}
		
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			
			View view = convertView;
			if (null == view) {
				LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(LAYOUT_INFLATER_SERVICE);
				view = inflater.inflate(mRes, parent, false);
				
				ImageView icon = (ImageView) view.findViewById(R.id.imageView1);
				MyLog.i(icon + "");
				
				if (mData.get(position).startsWith("and")) {
					icon.getDrawable().setAlpha(0);
//					icon.getDrawable().mutate().setAlpha(0);
				}
			}
			return view;
		}
		
	}
}
 布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent" android:layout_height="fill_parent"
	android:gravity="center_vertical">
	<ImageView android:layout_height="wrap_content" android:src="@drawable/icon"
		android:layout_width="wrap_content" android:id="@+id/imageView1"></ImageView>
	<TextView android:text="TextView" android:id="@+id/textView1"
		android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>

</LinearLayout>
 不调用mutate()时截图如下(ImageView都变成透明的了, 所以看不见)
 
调用mutate()方法时截图如下(一个ImageView透明, 另一个不透明, 正确结果!)


 
 
  • 大小: 53.2 KB
  • 大小: 58.8 KB
  • 大小: 59 KB
  • 大小: 59.3 KB
  • 大小: 7.3 KB
  • 大小: 9 KB
0
0
分享到:
评论

相关推荐

    Android-android-gif-drawable用于在Android上显示动画GIF

    在Android应用开发中,有时我们需要在界面上展示动态GIF图像,这时`android-gif-drawable`库就显得非常实用。这个库是专门为在Android平台上高效、流畅地播放GIF动画而设计的。本文将深入探讨如何使用`android-gif-...

    android.R.drawable图标查看软件

    Android系统图标android.R.drawable下的所有图标查看软件

    Android所有系统资源图标android.R.drawable.xxx查看软件

    Android所有系统资源图标android.R.drawable.xxx查看软件 源码地址:http://blog.csdn.net/dianyueneo/article/details/7197067

    android-gif-drawable

    "android-gif-drawable" 是一个专门为 Android 平台设计的开源组件,它使得在 Android 应用中轻松处理和展示 GIF 动态图变得轻而易举。这个库的目的是提供一个高效且功能丰富的解决方案,以替代系统默认对 GIF 支持...

    android资源图片浏览,系统图片,android.R.drawable浏览,查看系统图片,查看android自带图片

    `android.R.drawable`是Android SDK提供的一个预定义的资源集合,包含了大量的图标和图形,适用于各种UI组件和状态。 首先,我们要理解`android.R.drawable`是什么。这是一个Java类,它包含了Android系统提供的默认...

    android-gif-drawable解决5.0适配

    `android-gif-drawable`库由Sebastian Staudt开发,其核心目标是为Android平台提供高性能的GIF显示功能。该库不仅解决了Android 5.0之前的兼容性问题,还提供了丰富的API和配置选项,使得开发者可以更加灵活地控制...

    android_gif_drawable(播放gif图片)

    `android_gif_drawable`库就是为了帮助开发者在Android应用中方便地播放GIF图像而设计的。这个库提供了一个自定义的View,可以无缝集成到你的UI中,让你的应用能够支持动态的GIF内容。 首先,让我们了解一下GIF图片...

    Android应用源码之android-gif-drawable 支持fig显示的view.zip

    首先,`android-gif-drawable`库解决了原生Android SDK对GIF支持的不足。在Android的默认实现中,GIF图片通常被解析为静态图像,无法播放动画。`android-gif-drawable`通过提供一个可绘制对象(Drawable)来解决这个...

    android-gif-drawable 支持gif显示DEMO

    `android-gif-drawable`是一个强大的库,专门用于在Android应用中流畅地显示GIF格式的图像。这个库是开源的,可以在GitHub上找到最新的版本。`android-gif-drawable`提供了高效且低内存占用的解决方案,以确保在各种...

    Android代码-android-gif-drawable

    android-gif-drawable Views and Drawable for animated GIFs in Android. Overview Bundled GIFLib via JNI is used to render frames. This way should be more efficient than WebView or Movie classes. ...

    Android-android-gif-drawable.zip

    Android-android-gif-drawable.zip,在android上显示动画gif的视图和绘图,安卓系统是谷歌在2008年设计和制造的。操作系统主要写在爪哇,C和C 的核心组件。它是在linux内核之上构建的,具有安全性优势。

    Android应用源码之android-gif-drawable 支持fig显示的view-IT计算机-毕业设计.zip

    它提供了比原生Android SDK更强大的功能,比如动画控制、内存管理和性能优化。在源码中,我们可以看到如何集成这个库到项目中,以及如何利用其提供的API来播放、暂停、停止或改变GIF动画的速度。 在Android应用中...

    android-gif-drawable-master.zip_android_android gif

    Android SDK并没有提供内置的API来直接播放GIF,开发者通常需要借助第三方库来实现这一功能。`android-gif-drawable`就是这样一个库,它提供了一个可定制的`GifDrawable`类,可以被用作ImageView的源,轻松地在...

    android-gif-drawable最快最流畅GIF

    android-gif-drawable最快最流畅的GIF,带源码带so库,带范例!不像很多其他资源,虽说用了android-gif-drawable的开源项目,但是没有编译so,也没有上传,你下载他的根本用不了!因此特意上传亲测可以直接使用的给...

    android中的drawable集合

    在Android开发中,Drawable是图形和图像处理的重要组成部分,它是一种可以绘制到Canvas上的对象,广泛用于界面元素的装饰和状态表示。以下是对Android中drawable集合的详细解释: 1. **Bitmap Drawable**: Bitmap ...

    Android图像介绍-Drawable

    Android SDK提供了多种Drawable的实现类,如BitmapDrawable、NinePatchDrawable、ShapeDrawable等,每种类型都有其特定的用途和优势。 1. BitmapDrawable:这是最常见的Drawable类型,用于显示位图图像(.png, .jpg...

    android-gif-drawable-master.jar

    开源库 android-gif-drawable使用的jar包,使用详见博客http://blog.csdn.net/u012587637/article/details/18596465

Global site tag (gtag.js) - Google Analytics