事实上每一个View中都有Canvas能够用来绘制动画。仅仅须要在这个View中重载onDraw()方法就能够,可是SurfaceView类是一个专门用来制动动画的类。

Canvas(中文叫做"画布")就和HTML5中的canvas标签一样能够在一定区域内自由绘制图形。Canvas+SurfaceView制作的动画与View Animation和Property Animation这类动画比起来更加适合大量的集中播放的动画,比方游戏画面、相机的图像显示等。

由于SurfaceView一般会在还有一个专门的线程中不断重绘界面。所以不像其它动画那样要在主线程(UI线程)中播放动画的同一时候还要消耗一定的流畅度用来响应用户输入。

在使用SurfaceView时须要注意以下这些要点:

1)每一个SurfaceView都须要一个SurfaceHolder对象来处理这个SurfaceView的生命周期和获取这个SurfaceView的Canvas对象,能够通过调用SurfaceView的getHolder()方法来获取它的SurfaceHolder对象。

2)使用SurfaceView时通常是通过继承SurfaceView的方式来实现,能够顺便implements两个接口,各自是Runnable和SurfaceHolder.Callback。第二个接口须要重载三个函数,这三个函数就是SurfaceView的生命周期处理了,能够通过SurfaceHolder对象的addCallback()方法把实现好的Callback对象传进去。

3)在使用SurfaceView的Canvas时一定要记得加锁同步。由于不能让画布同一时候绘制多个图案,通过调用这个SurfaceView的SurfaceHolder对象的lockCanvas()就能够做到这一点。绘制完成后在调用SurfaceHolder对象的unlockCanvasAndPost()方法就能够解锁并更新。

以下给出了一个用SurfaceView和Canvas绘制动画的样例,一般直接复制上就能够执行看到效果:

package com.example.canvastest;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast; public class MainActivity extends Activity {
/*
* 这个类用来当測试的物件,会沿着方形路线持续移动
*/
class GameObject {
private float x;
private float y;
private Bitmap img;
private Paint paint; public GameObject() {
this.img = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
this.x = 100;
this.y = 100;
this.paint = new Paint();
} // 在SurfaceView加锁同步后传给自己的Canvas上绘制自己
public void drawSelf(Canvas canvas) {
canvas.drawBitmap(img, x, y, paint);
} // 获取物件下一次要绘制的位置(这里是沿着一个边长为400的正方形不断运动的)
public void getNextPos() {
if (y == 100 && x != 500)
x += 5;
else if (x == 500 && y != 500)
y += 5;
else if (y == 500 && x != 100)
x -= 5;
else if (x == 100 && y != 100)
y -= 5;
}
} /*
* 这个类就是加工了SurfaceView之后的类,全部要运动的物件都终于放在这里进行绘制
*/
class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
private Thread thread; // SurfaceView通常须要自己单独的线程来播放动画
private Canvas canvas;
private SurfaceHolder surfaceHolder; private GameObject obj; public MySurfaceView(Context c) {
super(c);
this.surfaceHolder = this.getHolder();
this.surfaceHolder.addCallback(this);
this.obj = new GameObject();
} @Override
public void run() {
while (true) {
obj.getNextPos();
canvas = this.surfaceHolder.lockCanvas(); // 通过lockCanvas加锁并得到該SurfaceView的画布
canvas.drawColor(Color.BLACK);
obj.drawSelf(canvas); // 把SurfaceView的画布传给物件。物件会用这个画布将自己绘制到上面的某个位置
this.surfaceHolder.unlockCanvasAndPost(canvas); // 释放锁并提交画布进行重绘
try {
Thread.sleep(10); // 这个就相当于帧频了,数值越小画面就越流畅
} catch (Exception e) {
e.printStackTrace();
}
}
} @Override
public void surfaceDestroyed(SurfaceHolder arg0) {
Toast.makeText(getApplicationContext(), "SurfaceView已经销毁", Toast.LENGTH_LONG).show();
} @Override
public void surfaceCreated(SurfaceHolder arg0) {
Toast.makeText(getApplicationContext(), "SurfaceView已经创建", Toast.LENGTH_LONG).show();
this.thread = new Thread(this);
this.thread.start();
} @Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// 这里是SurfaceView发生变化的时候触发的部分
}
} @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MySurfaceView(getApplicationContext())); // 别忘了開始的时候加载我们加工好的的SurfaceView
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}

假设转载请注明出处:http://blog.csdn.net/gophers

Android中使用SurfaceView和Canvas来绘制动画的更多相关文章

  1. android中画弧函数canvas.drawArc()之理解

    在学习android中图形图像处理技术这部分内容时,对绘制圆弧函数canvas.drawArc()的用法.参数含义及画图原理很是不理解,在网上搜索了一些,加上自己的理解,在此做个小总结,作为学习过程中 ...

  2. android中使用surfaceview+MediaPlayer播放视频

    Android中播放视频主要有两种方式: 使用其自带的播放器.指定Action为ACTION_VIEW,Data为Uri,Type为其MIME类型 使用android自带的VideoView,这种方法 ...

  3. Android中实现一个简单的逐帧动画(附代码下载)

    场景 Android中的逐帧动画,就是由连续的一张张照片组成的动画. 效果 注: 博客: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 ...

  4. Android中surface,surfaceview,sufaceholder以及surface客户端的关系

    这里以照相机camera功能的实现来解释surface,surfaceview,sufaceholder以及surface客户端(本例子中指的是camera)的关系,surface及其client(客 ...

  5. Android中使用SurfaceView+MediaPlayer+自定义的MediaController实现自定义的视屏播放器

    效果图如下: (PS本来是要给大家穿gif动态图的,无奈太大了,没法上传) 功能实现:暂停,播放,快进,快退,全屏,退出全屏,等基本功能 实现的思路: 在主布局中放置一个SurfaceView,在Su ...

  6. iOS的 context 和Android 中的 canvas

    ios 想要绘图,要用到CGContextRef类.最基本的用法是在- (void)drawRect:(CGRect)rect 函数中绘制. Android 中要用到Canvas类.最基本的用法是在  ...

  7. Android中绘制圆角矩形图片及任意形状图片

    圆角矩形图片在苹果的产品中很流行,相比于普通的矩形,很多人都喜欢圆角矩形的图片,因为它避开了直角的生硬,带来更好的用户体验,下面是几个设计的例子: 下面在Android中实现将普通的矩形图片绘制成圆角 ...

  8. Android中SurfaceView的使用详解

    Android中SurfaceView的使用详解 http://blog.csdn.net/listening_music/article/details/6860786 Android NDK开发 ...

  9. Android中的Interpolator

    Android中的Interpolator Interpolator用于动画中的时间插值,其作用就是把0到1的浮点值变化映射到另一个浮点值变化. 本文列出Android API提供的Interpola ...

随机推荐

  1. Android 代码混淆

    什么是代码混淆 Java 是一种跨平台的.解释型语言,Java 源代码编译成中间”字节码”存储于 class 文件中.由于跨平台的需要,Java 字节码中包括了很多源代码信息,如变量名.方法名,并且通 ...

  2. 教师简介 (Alma Del Tango的小站)

    教师简介 (Alma Del Tango的小站) Esteban Peng (TT) & Emilia Jia (Amy) TT和Amy是北京极具影响力的专业舞者,他们从07年开始推广阿根廷探 ...

  3. iOS 获取当前时间以及计算年龄(时间差)

    获取当前时间 NSDate *now = [NSDate date]; NSLog(@"now date is: %@", now); NSCalendar *calendar = ...

  4. 6.MIL采集和实时显示

    前面讲到的都是离线的图像获取方法,实际中我们做机器视觉都是在线采集图像和处理,处理结果决定了计算机要给出的控制信号如电机运动等,这样就实现了实时视觉反馈运动.MIL中的采集需要Matrox采集板卡的支 ...

  5. Spring3表达式语言(SpEL)学习笔记

    最新地址请访问:http://leeyee.github.io/blog/2011/06/19/spring-expression-language Spring Excpression Langua ...

  6. Codeforces Round #306 (Div. 2) D.E. 解题报告

    D题:Regular Bridge 乱搞. 构造 这题乱搞一下即可了.构造一个有桥并且每一个点的度数都为k的无向图. 方法非常多.也不好叙述.. 代码例如以下: #include <cstdio ...

  7. POJ 3481 &amp; HDU 1908 Double Queue (map运用)

    题目链接: PKU:http://poj.org/problem?id=3481 HDU:http://acm.hdu.edu.cn/showproblem.php?pid=1908 Descript ...

  8. C++学习之路—引用(一)—基础知识

    (根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 对一个数据可以建立一个“引用”,它的作用是为一个 ...

  9. 测试framebuffer

    static GGLContext *gr_context = 0; static GGLSurface gr_framebuffer[2]; static unsigned gr_active_fb ...

  10. JDK 安装以及环境变量的配置(Windows)

    首先下载对应版本的jdk ,然后安装,这里使用的是jdk 1.7的安装的 这个时候,JDK 已经安装完成,打开cmd 输入 java -version 就可以查看到,当前JDK 的版本如图 JDK 安 ...