《【Android开发API】应用程序资源 - 画布和绘制 - Canva》由会员分享,可在线阅读,更多相关《【Android开发API】应用程序资源 - 画布和绘制 - Canva(5页珍藏版)》请在金锄头文库上搜索。
1、原文:Canvas and Drawables翻译:用户:D.Winter|D.WinterAndroid框架提供系列2D绘画API,它允许你在画布上渲染自定义的图像和定制已经存在的视图的外型与体验。当绘制2D图像时,你将会使用代表性的两种方法:a.* 通过布局在视图对象里绘制你的图像或者动画* 。这种方法,你的图像句柄被系统标准视图层绘制进程控制。你简单定义将图像插视图中。b.* 直接在画布上绘制图像* 。此方法,你要亲自调用相应类的onDraw()方法 (passing it your Canvas), 或者其中个画布draw开头的方法(比如drawPicture()。这样做,你还:在控制
2、任意的动画。在你绘制简单图像时,方法a是最好的选择。它不需要不断改变也不属于高性能游戏。比如,你在视图中想要绘制静态的或者预先确定的动画在另外的静态应用中。更多信息请查看Drawables。当你的应用需要规律性的在画布上重绘时,方法b更为合适。就像电游戏,你要自重绘画布。然而,我们还有其他方法来实现: * 在UI Activity的同线程里创建的自定义视图组建中,调用invalidate()再控制onDraw()回调. *或者,在单独的线程中, 管理个SurfaceView并在画布中绘图(你不需要请求invalidate()。当你开发个应用专门来完成绘制和控制图像的动画,你应该使用画布。画布作
3、机制就像个接,你表面图像将会被绘制。它控制所有绘画调用。通过画布,隐藏的位图(Bitmap)v完成了绘图。它被放在窗体里。在onDraw()的回调方法事件中绘图,你只需要调用画布即可。当处理SurfaceView对象时,你也可以从SurfaceHolder.lock Canvas()获取个画布。(所有这些场景将在下面的章节中讨论。)然而,你需要创建个新的画布,你必须定义个实际执行的位图Bitmap。这个位图Bitmap是画布所必须的。你可以像这样设置个新画布:Bitmap b = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); C
4、anvas c = new Canvas(b);现在你的画布将绘制你定义的位图Bitmap。你还可以将这个位图Bitmap移到另外个画布,使用Canvas.drawBitmap(Bitmap,.)方法。通过View.onDraw()或SurfaceHolder.lockCanvas()获得画布绘制图像的方法是值得推荐的。(请看下面章节).Canvas类有自的设置绘画方法。像drawBitmap(.), drawRect(.), drawText(.)等等。你会用到的其他类也会有draw()方法。比如,你有可能有些Drawable对象需要放到画布中。Drawable有自的draw()方法,并将C
5、anvas作为参数。* View 绘图绘图*如果你的应用不需要量的处理或者帧速率(或许是个棋类游戏,贪吃蛇,或者其他),你应该考虑创建个自定义的View组件并通过View.onDraw()在画布中绘制。Android框架提供了预定义的Canvas来完成绘图调用,这么做是最方便的。首先, 继承View类(或者其类)并且定义onDraw()回调方法。这个方法在接到Android框架绘图请求时被调用。通过onDraw()回调执行所有画布绘图方法。1/eoe 移动开发者社区Android框架必须只调用onDraw()方法。每时每刻你的应用准备被绘制,你必须调用invalidate()使View无效。这
6、表面你将会看到你的View被绘制,Android将会随即调用你的onDraw()方法(尽管不能保证实时的回调)。在你的View组件onDraw()里,使用画布进行所有的绘制,使用各种Canvas.draw.()方法,或者其他类的draw()方法他们以Canvas作为参数。当onDraw()完成后,Android框架使用你的Canvas绘制位图Bitmap由系统控制.* 注意: 为了从个非主Activity的线材请求invalidate,你必须调用postInvalidate()(http:/ .继承View类的信息,请看自定义组件。对于个简单的应用程序,请看贪吃蛇, 在SDK案例文件: /sa
7、mples/Snake/.* SurfaceView 绘图绘图*SurfaceView是View的个特殊的类,提供个专用的绘图表面,在View层。应用程序的次级线材中加绘制,这样应用就不需要等到View层绘制完才能被请求。而且,副线程引用的SurfaceView可以绘制和控制自的画布。首先,你要创建个SurfaceView的类。这个类同时要实现SurfaceHolder.Callback。这个接将反馈你底层的信息,比如什么时候创建,改变或者销毁。知道这些事件非常重要,你可以知道什么时候开始绘制,你是否需要对新外观属性的进行调整,和当你停止绘制并销毁些任务。在SurfaceView类是定义副线程
8、的好地方,它执行画布的所有绘制过程。你应该通过SurfaceHolder,而非直接控制Surface对象。这样,当你的SurfaceView初始化,通过getHolder()获得SurfaceHolder。通知SurfaceHolder你要接收SurfaceHolder回调(SurfaceHolder.Callback)通过addCallback()。在SurfaceView class里覆盖所有SurfaceHolder.Callback方法。为了在副线程中绘制界面画布,你必须传递线程到SurfaceHandler并且通过lockCanvas()获得画布。你现在可以通过SurfaceHold
9、er获得画布并且在上面绘图了。当你在画布上绘制时, 调用unlockCanvasAndPost() ,传递到你的Canvas对象中。界面现在将绘制这个画布只要你关闭它。执行系列的加锁解锁在你每次想要重绘时。注: 在每次你从SurfaceHolder获得画布时,Canvas之前的状态将会被保留。为了绘制正确的动画效果,你必须重绘所有的界面。比如,你可以通过填充颜色drawColor()(http:/ /samples/LunarLander/。或者,在案例代码篇章浏览源代码。Android为图形图像提供自定义2D图像处理库。你可以在android.graphics.drawable包里找到针对位
10、绘图的公共类。本篇章讨论使用Drawable对象绘图的基础,和如何使用Drawable类的多个类。使用Drawables来绘制帧动画,请看Drawable Animation。Drawable的基本含义是内容是可绘的,你会发现Drawable类被扩展用于各种各样的可绘制图像,包2/eoe 移动开发者社区括BitmapDrawable, ShapeDrawable, PictureDrawable, LayerDrawable等等。当然,你也可以继承它们来定义自的Drawable对象。有三种方法定义和实例化个Drawable:使用项目资源中的图像;使用XML文件定义Drawable属性;或者使用
11、般的类构造函数。下面,我们将讨论前面两种方法(使用构造函数并没有什么新颖的地方)。* 由资源图像创建由资源图像创建*个简单的方法添加图像到你的应用中去,就是从你的项目资源里引用图片文件。支持PNG(首选),JPG(还行)和GIF(最好不要)文件类型。当你添加图标、logo时这个方法是首选的。为了使用图像资源,你要添加文件到项目目录res/drawable/下。从那你可以通过代码或者XML布局引用它们。不管怎样,都要通过资源ID来引用它,ID即为不包含扩展名的文件名(比如,my_image.png就为my_image)。* 注: 在编译过程中,res/drawable/里的图像资源会被aapt具
12、自动无失真图像压缩。 比如,个真彩色PNG文件它不需要于256色会被调色板修改为8位PNG。这样相同质量的图片所占的内存就会更。所以要注意图片的进制文件在编译时会改变。如果你计划读取图片数据流来转换为位图,将他们放到res/raw/文件夹里,这里他们不会被优化。代码例下面的代码片段演示了怎样使用ImageView通过drawable资源来使用图片并将其添加到布局layout中。LinearLayout mLinearLayout;protected void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceStat
13、e);/ 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 tomatch the Drawable
14、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
15、= mContext.getResources(); Drawable myImage = res.getDrawable(R.drawable.my_image);注: 项目中所有唯的资源只有个维护状态,不管你用它实例化了多少对象。比如,你由同个资源图片实例化了2个Drawable对象,然后改变其中个的属性 (比如透明度),然后它也会影响到另外个。所以,在多个实例使用个图片资源时,不要直接转换为Drawable,你应该执行tweenanimation(http:/ layout中,向ImageView中添加图像资源。 更多关于项目资源的信息,请3/eoe 移动开发者社区看Resources
16、and Assets。* 由资源中的由资源中的XML文件创建文件创建*现在,您应该熟悉了Android的用户界面开发应遵循的些规则。因此,你知道由XML来定义对象是多么方便灵活了吧。这种方法不管Views还是 Drawables都适用。如果你要创建个Drawable对象,它不依赖于某个变量或者用户的交互,那么在XML里定义它是个好办法。即时你希望用户在体验时去改变它的属性, 你应该考虑在XML里定义, 你可以不断改变它的属性直到它被实例化。你旦在XML里定义了Drawable,在项目文件夹res/drawable/里保存。然后,通过调用Resources.getDrawable()来获取并实例
17、化它,传XML文件的资源ID。(请看下面的例)所有Drawable类支持inflate()方法,在XML里定义和实例化。利用特定的XML标签来定义对象属性。例:在XML里定义TransitionDrawable:XML文件保存为res/drawable/expand_collapse.xml,下面的代码演示怎么实例化TransitionDrawable和像ImageView样设置其内容。 Resources res = mContext.getResources(); TransitionDrawable transition =(TransitionDrawable) res.getDraw
18、able(R.drawable.expand_collapse); ImageView image = (ImageView)findViewById(R.id.toggle_image); image.setImageDrawable(transition); 然后这个transition会持续向前移动秒:transition.startTransition(1000);* Shape Drawable*当你动态的绘制些维图像时,ShapeDrawable对象会给你很的帮助。你能以编程的方式绘制基本形状和风格。ShapeDrawable是Drawable的扩展,所以在用到Drawable的时
19、候你同样可以使用ShapeDrawable。比如设置View的背景时,setBackgroundDrawable() 。 当然,你也可以在自定义的View里绘制你的模型。因为ShapeDrawable有自的draw()方法,你可以在View类onDraw()方法里绘制ShapeDrawable。 下面是最基本的例,绘制ShapeDrawable对象:public class CustomDrawableView extends View private ShapeDrawable mDrawable;在构造方法里, ShapeDrawable被定义为个OvalShape(椭圆模型)。然后设置颜
20、色和(界限)。 如果你不设置,模型不会被绘制。如果你不设置颜色,它将默认为黑色。在Activity里通过代码绘制自定义的View:CustomDrawableView mCustomDrawableView;如果你喜欢通过XML布局文件定义drawable来代替直接在Activity直接写代码,那它必须覆盖 View(Context,AttributeSet)构造方法,它在View从XML里获取初始化时被调用。然后添加CustomDrawable元素在XML里: ShapeDrawable类允许你通过drawable的public方法设置不同的属性。像调整透明度,颜色,抖动,滤色器等。你也可以
21、由XML定义drawable shapes。更多信息请看Drawable Resources4/eoe 移动开发者社区* Nine-patch*NinePatchDrawable图像是可伸展的位图。当你将它作为背景时,Android会自动适应View的。NinePatch的个案例是背景使用标准Android按钮。按钮必须能根据不同的长度自动伸展。NinePatch drawable是标准的PNG格式,在最外面圈额外增加1px的边框。它必须以.9.png为扩展名,并且保存在res/drawable/目录下。这个1px的边框就是用来定义图片中可扩展的和静态不变的区域。在边框的左上角画个1像素的黑线
22、来表面伸缩区域。你想要多少伸缩区域都可以:他们的绝对尺保持相同,所以最的区域永远是最的。你也可以定义个可选的可移动部分在图片上,通过下面和右边的线。如果个View对象设置NinePatch作为背景,然后改变View上的文字, 它会自伸展,所有的文字将会适应你通过右边和下面的线定义的区域。如果不包括填充线, Android使用左边和上面的线定义可绘区域。为了阐明这两条线的不同,左和上的线定义图片像素允许被复制以便拉伸图片。下方和右边的线定义相对区域在图片的内容区域。下面是简单的按钮使用例:http:/ 确定个View里的内容显示区域。如果内容不适合这个区域,图片将会被拉伸。Draw 9-patch具提供了简便的方法来创建我们的NinePatch图片,使用WYSIWYG图形具。Example XML注意宽和高设置为wrap_content使按钮内容自动调整。http:/ 本文链接: http:/ 移动开发者社区