本文译自:http://developer.android.com/guide/topics/graphics/2d-graphics.html
图形绘制
Android为绘制图形和图片提供了一个定制的2D图形类库。android.graphics.drawable包中能够找到用于绘制二维图形的共同的类。
本文讨论使用Drawable对象来绘制图形的基础知识,以及如何使用Drawable类的子类。关于使用Drawable对象来绘制帧动画的信息,请看绘制动画文档(http://developer.android.com/guide/topics/graphics/drawable-animation.html)
Drawable对象是对图形绘制的一般化抽象,你会发现很多用于绘制特殊类型图形的Drawable类的子类,包括BitmapDrawable、ShapDrawable、PictureDrawable、LayerDrawable等。当然,你也可以继承这些类,来定义自己的具有独特行为的Drawable对象。
有三种方法来定义和初始化一个Drawable对象:1.使用保存在项目资源中的一个图片;2.使用定义Drawable对象属性的XML文件;3.使用普通的类构造器。以下我们将重点讨论前两种技术(使用构造器技术对于开发者来说并不陌生)。
从资源图片中创建一个Drawable对象
通过引用项目资源中的一个图片文件,把图形添加到应用程序中是一种简单的方法。支持的图片格式包括:PNG(推荐格式)、JPG(可接受格式)、GIF(不推荐格式)。这种技术主要用于应用的图标、Logo或游戏中所使用的那些图形。
要使用图片资源,只需把图片添加到项目的res/drawable/目录中。应用程序代码或XML布局会从那儿来引用这些图片。无论在那儿使用图片,都要使用该图片资源的ID,这个ID是不带文件类型扩展名的文件名(如:my_image指向了my_image.png文件)。
注意:被放置在res/drawable/目录下的图片资源,在编译期间,能够被aapt工具自动的优化压缩成无损的图片。例如,一个不多于256色的真彩色PNG图片,能够被转换成一个带有调色板的8位PNG图片。这样就获得同等品质的图片,但却需要更少的内存。因此,要了解放置在这个目录下的图片,在编译期间的这种改变。如果为了把图片转换成一个位图,而计划用位流的形式来读取一张图片,就要把该图片放到res/raw/文件夹中,这个文件夹中的图片不会被优化。
示例代码
以下代码片段演示了如何创建一个使用绘制资源图片的ImageView对象,并把该对象添加到布局中:
LinearLayout mLinearLayout;
protectedvoid onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
// Create a LinearLayout in which to add the ImageView
mLinearLayout =newLinearLayout(this);
// Instantiate an ImageView and define its properties
ImageView i =newImageView(this);
i.setImageResource(R.drawable.my_image);
i.setAdjustViewBounds(true);// set the ImageView bounds to match the Drawable's dimensions
i.setLayoutParams(newGallery.LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
// Add the ImageView to the layout and set the layout as the content view
mLinearLayout.addView(i);
setContentView(mLinearLayout);
}
另一种情况,可能想要把图片资源作为Drawable对象来处理,就要像下面代码这样来创建一个Drawable对象:
Resources res = mContext.getResources();
Drawable myImage = res.getDrawable(R.drawable.my_image);
注意:在项目中的每种资源只能保持一种状态,不管实例化了多少该对象。例如:如果用同一个图片资源来实例化了两个Drawable对象,那么只要改变了其中一个Drawable对象一个属性(如,透明度),另一个也会受到影响。因此在处理一个图片资源的多个实例时,要用补间动画(tween animation)来替代直接的Drawable对象的传递。
示例XML
以下XML片段显示了如何把一个绘制资源添加到XML布局中的一个ImageView元素中:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tint="#55ff0000"
android:src="@drawable/my_image"/>
关于使用项目资源的更多信息,请看资源和资产文档(http://developer.android.com/guide/topics/resources/index.html)
从资源XML中创建一个Drawable对象
现在,你应该已经熟悉了Android的用户界面的开发原则。因此也就理解了定义XML中对象所带来的强大功能和灵活性。这种方法从View对象到Drawable对象都适用。如果创建了一个Drawable对象,它初始并不依赖应用程序代码或用户界面中定义的一个变量,而是把它定义在一个XML中,这是一个好的选择。即使是在用户与应用程序交互期间要改变Drawable对象的属性,也应该考虑把该对象定义在XML中,这样一旦它被实例化,就可以随时来修改它的属性。
一旦用XML来定义Drawable对象,就要把该定义保存在工程的res/drawable/目录中,然后通过调用Resources.getDrawable()方法来获取和实例化该对象。
任何提供了inflate()方法的Drawable子类都能够被定义在XML中,并能够被应用程序实例化。每个提供XML填充能力的Drawable对象,都采用了特殊的XML属性来帮助定义对象的属性。有关每个Drawable子类如何在XML中定义的信息,请看对应类文档。
示例
以下XML定义了一个TransitionDrawable对象:
<transitionxmlns:android="http://schemas.android.com/apk/res/android">
<itemandroid:drawable="@drawable/image_expand">
<itemandroid:drawable="@drawable/image_collapse">
</transition>
这个XML要保存在res/drawable/expand_collapse.xml文件中,以下代码会示例化该TransitionDrawable对象,并把它作为ImageView对象的内容来设置:
Resources res = mContext.getResources();
TransitionDrawable transition =(TransitionDrawable)
res.getDrawable(R.drawable.expand_collapse);
ImageView image =(ImageView) findViewById(R.id.toggle_image);
image.setImageDrawable(transition);
然后,这个过渡效果能够使用以下代码来运行:
transition.startTransition(1000);