一个简单的方法添加图像到你的应用中去,就是从你的项目资源里引用图片文件。支持PNG(首选),JPG(还行)和GIF(最好不要)文件类型。当你添加图标、logo时这个方法是首选的。
为了使用图像资源,你要添加文件到项目目录res/drawable/下。从那你可以通过代码或者XML布局引用它们。不管怎样,都要通过资源ID来引用它,ID即为不包含扩展名的文件名(比如,my_image.png就为my_image)。
* 注: 在编译过程中,res/drawable/里的图像资源会被aapt工具自动无失真图像压缩。
比如,一个真彩色PNG文件它不需要大于256色会被调色板修改为8位PNG。这样相同质量的图片所占的内存就会更小。所以要注意图片的二进制文件在编译时会改变。如果你计划读取图片数据流来转换为位图,将他们放到res/raw/文件夹里, 这里他们不会被优化。
代码例子
下面的代码片段演示了怎样使用ImageView通过drawable资源来使用图片并将其添加到布局layout中。
LinearLayout mLinearLayout;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Create a LinearLayout in which to add the ImageView
mLinearLayout = new LinearLayout(this);
// Instantiate an ImageView and define its properties
ImageView i = new ImageView(this);
i.setImageResource(R.drawable.my_image);
i.setAdjustViewBounds(true); // set the ImageView bounds to match the Drawable's dimensions
i.setLayoutParams(new Gallery.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);
注:
项目中所有唯一的资源只有一个维护状态,不管你用它实例化了多少对象。比如,你由同一个资源图片实例化了2个Drawable对象,然后改变其中一个的属性 (比如透明度),然后它也会影响到另外一个。所以,在多个实例使用一个图片资源时,不要直接转换为Drawable,你应该执行tween animation。
下面的XML片段展示怎么在XML layout中,向ImageView中添加图像资源。
更多关于项目资源的信息,请看Resources and Assets。
现在,您应该熟悉了Android的用户界面开发应遵循的一些规则。因此,你知道由XML来定义对象是多么方便灵活了吧。这种方法不管Views还是 Drawables都适用。如果你要创建一个Drawable对象,它不依赖于某个变量或者用户的交互,那么在XML里定义它是个好办法。即时你希望用户在体验时去改变它的属性, 你应该考虑在XML里定义, 你可以不断改变它的属性直到它被实例化。
你一旦在XML里定义了Drawable,在项目文件夹res/drawable/里保存。然后,通过调用Resources.getDrawable()来获取并实例化它,传入XML文件的资源ID。(请看下面的例子)
所有Drawable子类支持inflate()方法,在XML里定义和实例化。利用特定的XML标签来定义对象属性。
例子:
在XML里定义TransitionDrawable:
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会持续向前移动一秒:
transition.startTransition(1000);
当你动态的绘制一些二维图像时,ShapeDrawable对象会给你很大的帮助。你能以编程的方式绘制基本形状和风格。
ShapeDrawable是Drawable的扩展,所以在用到Drawable的时候你同样可以使用ShapeDrawable。比如设置View的背景时,setBackgroundDrawable() 。 当然,你也可以在自定义的View里绘制你的模型。因为ShapeDrawable有自己的draw()方法,你可以在View子类onDraw()方法里绘制ShapeDrawable。
下面是最基本的例子,绘制ShapeDrawable对象:
public class CustomDrawableView extends View {
private ShapeDrawable mDrawable;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
public CustomDrawableView(Context context) { super(context); int x = 10; int y = 10; int width = 300; int height = 50; mDrawable = new ShapeDrawable(new OvalShape()); mDrawable.getPaint().setColor(0xff74AC23); mDrawable.setBounds(x, y, x + width, y + height); } protected void onDraw(Canvas canvas) { mDrawable.draw(canvas); } }
在构造方法里, ShapeDrawable被定义为一个OvalShape(椭圆模型)。然后设置颜色和大小(界限)。 如果你不设置大小,模型不会被绘制。如果你不设置颜色,它将默认为黑色。
在Activity里通过代码绘制自定义的View:
CustomDrawableView mCustomDrawableView;
1 2 3 4 5 6
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mCustomDrawableView = new CustomDrawableView(this); setContentView(mCustomDrawableView); }
如果你喜欢通过XML布局文件定义drawable来代替直接在Activity直接写代码,那它必须覆盖 View(Context, AttributeSet)构造方法,它在View从XML里获取初始化时被调用。然后添加CustomDrawable元素在XML里:
ShapeDrawable类允许你通过drawable的public方法设置不同的属性。像调整透明度,颜色,抖动,滤色器等。
你也可以由XML定义drawable shapes。更多信息请看Drawable Resources