- 浏览: 115220 次
- 性别:
- 来自: 合肥
最新评论
Android开发指南-二维图形
二维图形2D Graphics
Android 提供一个定制的2D图形库,用来绘制图形图像和制作动画。你将从android.graphics.drawable和android.view.animation包中找到这些通用类。
本文简单介绍如何在Android应用程序中进行画图。我们将讨论使用Drawable对象画图的基础知识,如何使用几个Drawable子类,以及如何创建动画,一个图形的补间动画或者一系列图形的连续动画(就像电影胶卷一样)。
可绘制物Drawables
一个Drawable 是一个“某些可以被绘制的物体”的一般抽象。你将发现这个Drawable类扩展了多种具体可绘制图形类,包括BitmapDrawable, ShapeDrawable, PictureDrawable, LayerDrawable, 等等。当然,你还可以扩展这些类来定义你自己的具有独特行为的可绘制对象。
有三种方式来定义和实例化一个Drawable:使用一个保存在你的项目资源中的图像;使用一个定义了Drawable属性的XML文件;或者使用通常的类构造函数。下面,我们将挨个讨论前面两种方法(对于一个经验丰富的开发人员而言,使用构造函数没什么新意)。
从资源图像中创建Creating from resource images
一个为你的应用程序增加图形的简单方法是通过引用项目资源中的一个图片文件。支持的图片文件格式有PNG(推荐的),JPG(可接受的)和GIF(不鼓励的)。这个技术将显然推荐使用在应用程序图标,logo,或者其它类似使用于游戏中的图形。
为了使用一个图片资源,只要把你的文件添加到你项目的res/drawable/目录即可。从那里,你可以在代码或XML布局中进行引用。任何一种方式,都是通过资源ID来引用,资源ID是不带扩展后缀的文件名(比如,my_image.png通过my_image来引用)。
注意: 图像资源被放在res/drawable/里。也许会通过aapt工具进行无损图像压缩而被自动优化。比如,一个不需要多于256色的真彩色PNG图片可能会被转换成一个带有调色板的8位PNG。这产生了相同质量但占用更少内存的图片。因此需要意识到该目录下的二进制图像可能会在编译期间被改变。如果你想以比特流读取一个图片并转换为一个位图,那么需要把你的图片文件放在res/raw/目录,这里的文件不会被优化。
示例代码Example code
下面的代码片断说明了如何构造一个ImageView,从drawable资源中使用并添加到布局中。
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对象。为此,你可以这样做:
Resources res = mContext.getResources();
Drawable myImage = res.getDrawable(R.drawable.my_image);
注意: 每个你项目里的唯一资源只能维护一个状态,而无论你为它实例化了多少个不同对象。比如,如果你从相同的图像资源实例化两个可绘制对象,然后改变其中之一的属性(比如alpha),那它也将作用于另一个。所以当处理一个图片资源的多个实例时,你应该实施一个tween animation,而不是直接转换这个可绘制对象。
示例XML
下面的XML片断显示了如何添加一个可绘制资源到一个XML布局中的ImageView里(为了有趣些,添加一些红色渲染)。
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tint="#55ff0000"
android:src="@drawable/my_image"/>
更多关于使用项目资源的信息,请阅读资源和资产Resources and Assets。
从资源XML中创建Creating from resource XML
到目前为止,你应该对Android用户界面User Interface的开发原理比较熟悉。因此,你应该了解在XML中定义对象所固有的能力和灵活性。这个理念从视图延伸到可绘制对象。如果你想创建一个可绘制(Drawable)对象,而它并不初始依赖于你代码中的变量或者用户交互,那么在XML里面定义它是个好的选择。即便你预期这个可绘制对象在用户使用你的应用程序时将会改变其属性,你也应该考虑在XML里面定义它,因为一旦被实例化后,你就可以修改它的属性。
一旦你在XML中定义了你的可绘制对象,把这个文件保存到你项目中的res/drawable/ 目录下。然后,通过传递资源ID参数调用Resources.getDrawable()获取并实例化这个对象。 (参见example below.)
任何支持inflate()方法的可绘制对象(Drawable)子类可以在XML里定义并由你的应用程序实例化。每个支持XML扩充的可绘制对象利用特定的XML属性来帮助定义对象属性(参见类参考了解这些属性)。查阅每个可绘制对象子类的类描述文档,以获知如何在XML中定义它。
例子Example
下面是一些定义了一个TransitionDrawable对象的XML语句:
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/image_expand">
<item android:drawable="@drawable/image_collapse">
</transition>
当把这个XML保存为res/drawable/expand_collapse.xml文件后,下面的代码将用来实例化它并把它设置为一个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运转起来(每1秒转变一次):
transition.startTransition(1000);
请参考上面所列的可绘制对象(Drawable)类以了解更多它们所支持的XML属性。
可绘制形状ShapeDrawable
当你想动态的画一些二维图形时,ShapeDrawable对象可能会满足你的要求。 通过一个ShapeDrawable,你可以绘制原始图形和以任何想象得到的方式设计它们。
ShapeDrawable是Drawable的一个扩展类,因此你能使用在任何可用Drawable的地方- 也许是视图背景,用setBackgroundDrawable()方法来设置。当然,你还能以它自己的视图来绘制图形,并添加到你的布局中只要你乐意。因为ShapeDrawable有它自己的draw()方法,你可以创建一个视图子类在View.onDraw()方法中绘制这个ShapeDrawable。下面这个视图类的一个基本扩展就是这么做的,把ShapeDrawable作为一个视图来绘制。
public class CustomDrawableView extends View {
private ShapeDrawable mDrawable;
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。然后设置颜色和边界。如果你不设置边界,那么这个图形将不被绘制,不过如果你不设置颜色的话,它会设置成缺省的黑色。
通过这个定制视图,它能以任何你想要的方式绘制。通过上面的例子,我们能在一个活动中以编程的方式绘制这个图形:
CustomDrawableView mCustomDrawableView;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mCustomDrawableView = new CustomDrawableView(this);
setContentView(mCustomDrawableView);
}
如果你希望从XML布局中而不是活动中绘制这个自定义可绘制对象,那么这个CustomDrawable类必须重写View(Context, AttributeSet) 构造函数,这个当通过XML扩充来实例化一个视图时被调用。然后为这个XML添加一个CustomDrawable元素,如下:
<com.example.shapedrawable.CustomDrawableView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
这个ShapeDrawable类(像很多其他在android.graphics.drawable包中的可绘制对象类型一样)允许你通过公共的方法来定义这个可绘制对象的各种属性。有一些属性,你可能会做一些调整,比如alpha透明度,颜色过滤器,抖动,模糊度和颜色。
可绘制九宫格
一个NinePatchDrawable图形是一个可拉伸位图图像,Android会自动调整来容纳视图的内容,你可以用来作为背景。一个使用九宫格的例子是Android按钮背景-按钮必须延伸以适应各种长度的字符串。一个九宫格可绘制对象是一个标准的PNG图像,并包含一个附加的单像素宽的边界。它必须以扩展名.9.png保存,并存放到res/drawable/目录。
这个边界用来定义这个图像的可拉伸和静态区域。通过在边界的左边和上面部分绘画单像素宽的一个或多条黑线来指示一个可拉伸区。(你能有任意多的可拉伸区)。这些可拉伸区的相对尺寸保持一样,因此最大的区域总是保持最大。
你也可以通过在右边和下面画线来定义这个图片(事实上,这些填充线)的一个可选的可绘制区。如果一个视图对象设置这个九宫格为其背景然后指定这个视图的文本,它将自我调整以使得文本适应在刚才通过右边和下面的画线指定的区域里面(如果被包含进来)。如果这些填充线未被包含,Android使用左边和上面的线来定义可绘制区域。
为了阐明不同线的区别,左边和上面定义了哪些图像像素允许被复制来拉伸这个图像。下面和右边的线则定义了这个图像中的相对区域,这个区域可允许视图内容显示于其中。
下面是一个用来定义一个按钮的九宫格文件例子:
这个九宫格通过左边和上面的线条定义了一个可拉伸区域以及通过下面和右边的线条定义了一个可绘制区域。在图中上半部分,灰色的虚线标示了可以被复制来拉伸图像的区域。而下半部分的粉红虚线框标示了允许显示视图内容的区域。如果内容不能适应这个区域,那么这个图像将被拉伸来适应它。
Draw 9-patch 工具提供了一个非常方便的方法来创建你的九宫格图像,使用一个所见即所得的图像编辑器。它甚至会在你的可拉伸区域会产生人工痕迹时(复制像素的副效果)提出告警。
示例XMLExample XML
下面是一些示例布局XML来说明怎么添加一个九宫格图像到几个按钮中。(这个九宫格图像被保存为res/drawable/my_button_background.9.png)
<Button id="@+id/tiny"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerInParent="true"
android:text="Tiny"
android:textSize="8sp"
android:background="@drawable/my_button_background"/>
<Button id="@+id/big"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerInParent="true"
android:text="Biiiiiiig text!"
android:textSize="30sp"
android:background="@drawable/my_button_background"/>
注意宽度和高度被设置为"wrap_content",这样按钮可以整齐得体的适合文本。
下面两个按钮以XML和上面显示的九宫格图像进行绘制。注意按钮的高度和宽度如何根据文本大小进行相应调整,以及背景图片自动拉伸来容纳它。
补间动画Tween Animation
一个补间动画可以在视图对象的内容上执行一系列的简单变换(位置,尺寸,旋转和透明度)。因此,如果你有一个文本视图TextView对象,你可以移动,旋转,扩展或者收缩这个文本。如果它有一个背景图像,也将随着文本一起变换。动画包animation package 提供了所有补间动画需要使用的类。
一系列动画指令定义了这个补间动画,通过XML或者代码。就像定义一个布局一样,XML文件是推荐使用的方法,因为它比硬编码这个动画要更容易阅读,可复用和可交换。在下面的例子中,我们使用XML。(为了学习更多关于在你的应用程序中定义一个动画方面的知识,请参考AnimationSet 类和其他Animation 子类。)
动画指令定义你想要发生的变换,什么时候发生以及多长时间。变换可以是顺序的或者是同时发生的-比如,你可以让一个TextView的内容从左到右移动,然后旋转180度,或者你让它同时移动和旋转。每个变换采用一组特定参数(尺寸变化的起动以及结束尺寸,旋转的起动和结束角度,等等),和一组通用参数(比如,起动时间和持续时间)。要使若干变换同时发生,可以为它们设定相同的起动时间;要让它们顺序发生,计算起动时间为前置变换起动时间加上持续时间。
这个动画XML文件归属于res/anim/目录。该文件必须有一个单独的根元素:这将会是一个单独的<alpha>, <scale>, <translate>, <rotate>,插值器(interpolator)元素, 或包含这些元素组的<set> 元素(可能含有另一个<set>元素)。缺省情况下,所有的动画指令都是同时发生的。要让它们顺序发生,你必须指定startOffset 属性,如下例所示:
下面来自ApiDemos的XML文件被用来拉伸,然后同时旋转一个视图对象。
<set android:shareInterpolator="false">
<scale
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromXScale="1.0"
android:toXScale="1.4"
android:fromYScale="1.0"
android:toYScale="0.6"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="false"
android:duration="700" />
<set android:interpolator="@android:anim/decelerate_interpolator">
<scale
android:fromXScale="1.4"
android:toXScale="0.0"
android:fromYScale="0.6"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="700"
android:duration="400"
android:fillBefore="false" />
<rotate
android:fromDegrees="0"
android:toDegrees="-45"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="700"
android:duration="400" />
</set>
</set>
屏幕坐标(未在本例中使用)是基于左上角的 (0,0),向下和向右时坐标值增加。
一些数值,比如pivotX,可以被指定为对象自己或父对象的相对值。确保使用合适的格式(“50”表示相对于父对象的50%,或者“50%”表示相对于自己的50%)。
你可以通过分配一个插值器Interpolator来决定一个变换的时间特性。Android包含一些插值器子类来指定可以用在XML里的各种速度曲线属性值。
把这个XML保存为res/anim/目录下的hyperspace_jump.xml文件,下面的Java代码将从布局中引用它并把它应用到一个ImageView 对象。
ImageView spaceshipImage = (ImageView) findViewById(R.id.spaceshipImage);
Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);
spaceshipImage.startAnimation(hyperspaceJumpAnimation);
作为startAnimation()方法的一个替代,你可以通过Animation.setStartTime()定义一个动画起动时间,然后通过View.setAnimation()给这个视图分配一个动画。
更多关于XML语法,可用标签和属性的信息,参见可用资源Available Resources一章中关于动画部分的讨论。
注意: 不管你的动画将如何移动和调整大小,容纳你的动画的视图边界将不会自动调整来适应它。即便如此,动画将仍然会被绘制到边界以外而不会被裁剪。不过,如果超过父视图的边界则将被裁剪。
帧动画Frame Animation
这是一个经典动画,由一连串不同的图像,顺序播放而创建,就像电影胶卷一样。AnimationDrawable 类是帧动画技术实现的基础。
虽然你可以在代码中使用AnimationDrawable类的API定义一个动画的各个帧,但是通过在一个单独的XML文件中列举所有组成该动画的帧的方式实现起来要简单得多。和上面的补间动画一样,这种动画的XML文件归属于项目的res/anim/目录下。在这个情况下,指令是每个动画帧的顺序和持续时间。
这个XML文件由一个根元素<animation-list>和一系列定义帧的子<item>节点组成:一个表示帧的可绘制资源和帧持续时间。下面是一个例子XML文件:
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
<item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
<item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
</animation-list>
这个动画只有三帧。通过设置android:oneshot属性为true,它将只循环一次然后停在最后那一帧上。如果设置成false,那么动画将不断循环运行。通过把XML保存为res/anim/目录下的rocket_thrust.xml,它可以被添加为一个视图的背景图像然后播放。下面是一个例子活动,其中动画被添加到一个ImageView 并在触摸屏幕时启动动画:
AnimationDrawable rocketAnimation;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
rocketImage.setBackgroundResource(R.anim.rocket_thrust);
rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
rocketAnimation.start();
return true;
}
return super.onTouchEvent(event);
}
注意在AnimationDrawable上调用的start()方法不能在你的活动的onCreate()中调用,因为这个AnimationDrawable还没有被完全附着到窗口上。如果你想立即播放这个动画,而不需要请求交互,那么你可能要从活动的onWindowFocusChanged()函数中调用它,这将在窗口获得焦点时被调用
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/iefreer/archive/2009/09/30/4619697.aspx
相关推荐
综上所述,Android开发指南-二维图形指南涵盖了从基础的Drawable使用到复杂的动画效果实现的方方面面,是Android开发者在图形处理方面的重要参考文档。通过掌握这些知识点,开发者可以更好地控制Android应用的视觉...
在Android开发中,二维图形是构建用户界面和创建动态效果不可或缺的部分。Android提供了一个自定义的2D图形库,使得开发者能够绘制图形图像、创建动画,丰富应用的视觉体验。以下将详细介绍Android中二维图形的基本...
《OpenGL ES应用开发实践指南:Android卷》是一本系统的OpenGL三维游戏和动态壁纸开发指南。由资深Android开发专家根据OpenGLES2.0版本撰写,不仅系统地讲解了OpenGLES的核心概念、技术,以及Android的图形机制,还...
《OpenGL ES应用开发实践指南:Android卷》是一本系统的OpenGL三维游戏和动态壁纸开发指南。由资深Android开发专家根据OpenGLES2.0版本撰写,不仅系统地讲解了OpenGLES的核心概念、技术,以及Android的图形机制,还...
- **图像目标追踪**:Vuforia能够识别和追踪打印的图像或二维条码,将虚拟内容叠加到这些真实世界的目标上。 - **智能地形**:这项技术使Vuforia能够识别和追踪平坦表面,无需预先定义目标,允许用户在任何平面上...
本书的主要内容: 在本书第一部分,会学习如何创建一个简单的空气曲棍球游戏,包括触控、...如果对在Android上开发更高级的图形程序感兴趣,本书就是为你所写的。本书假定你有一些编程经验,包括Java和Android的经验。
- **图像**:在Vulkan中,图像表示一个二维或多维的数据数组,可以用于纹理、渲染目标等多种用途。 以上就是《Vulkan编程指南》中的主要知识点概述。通过学习这些内容,开发者可以深入理解Vulkan的工作原理,并掌握...
- **第11章 2D动画**:教授如何实现流畅的二维动画效果。 - **第12章 OpenGLES编程**:介绍基于OpenGL ES的图形渲染技术。 - **第13章 资源、国际化与自适应**:讨论如何优化应用的资源管理,支持多语言环境和...
- 三维图形绘制实战案例 9. **应用发布流程**: - 创建Google Play开发者账号 - 应用上架前的准备工作 - 版本管理与更新发布策略 #### 四、教材优势与适用人群 - **优势**:本书内容详实、结构清晰,特别注重...
Material Design引入了"材料"的概念,它是一种虚拟的二维表面,通过颜色、阴影和动画来表达深度。在信号强度视图中,我们可以利用这些原则来创建具有真实感的图形元素,如滑块或指示条,以展示信号的强弱。 Android...
《Beginning Android Games 2012》还详细介绍了OpenGL ES,这是一种在Android平台上广泛使用的图形API,专门用于渲染二维和三维图形。书中为读者提供了对OpenGL ES的温和入门,解释了其工作原理和在游戏开发中的应用...
《ArcEngine开发指南》 ArcEngine是Esri公司推出的一款强大的地理信息系统(GIS)开发平台,它为开发者提供了丰富的API和工具,使得开发者能够构建基于桌面、Web以及移动设备的应用程序,实现对地理数据的创建、...
《Pro Android Games》是一本专为希望学习并掌握Android游戏开发的开发者编写的指南。通过详细的理论讲解和丰富的实践案例,本书不仅能够帮助初学者快速入门,还能让有一定经验的开发者进一步提升技能。无论你是想...
1. **扁平化设计**:摒弃了之前版本中的阴影和质感,采用更加简洁、二维的元素,同时通过光影效果来创建深度感。 2. **色彩**:Android L引入了丰富的颜色系统,允许开发者使用大胆鲜艳的色彩来突出关键信息,同时...
- **游戏界面实现**:利用二维数组`mTileGrid`存储每个网格的图像索引,通过`setTile()`方法设定特定位置的图像类型,如蛇身、苹果或障碍物。同时,通过`loadTile()`加载图像资源到`Bitmap`中,确保游戏界面的丰富性...
- 棋盘通常是一个二维数组,表示棋盘的格子。每个元素代表一个格子,可以通过行和列的坐标来访问。初始化时,所有格子状态默认为空。 - 使用`GridView`或自定义的`LinearLayout`来布局棋盘界面,每个格子对应一个...
第二部分讨论Android的用户界面、二维图形、多媒体组件以及简单的数据访问。这些特性在大多数程序中都用得到。 第三部分深入探讨Android平台。这一部分介绍外部通信、基于位置的服务、内置SQLite数据库和三维...
《Android连连看源码解析与游戏开发指南》 在Android平台上开发一款连连看游戏,对于初学者来说,是一个很好的实践项目。"android连连看源码"提供了完整的代码实现,可以帮助开发者深入理解Android游戏开发的基本...
在OpenGL ES中,顶点可以通过二维坐标(X, Y)或三维坐标(X, Y, Z)来表示。此外,还可以使用四维坐标(X, Y, Z, W),其中W轴是可选的,默认值为1.0。在大多数情况下,我们会使用三维坐标来定义顶点位置。 - **三角形...
在Android平台上,OpenGL是一个强大的图形库,用于渲染2D和3D图像。本文将深入探讨如何使用OpenGL在Android上绘制STL(立体光刻)3D模型,特别关注创建一个3D指南针效果。STL是一种广泛用于3D打印和计算机辅助设计...