事实上每一个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. 《C++ Primer Plus》学习笔记1

    C++ Primer Plus>学习笔记1 第二章.開始学习C++ 1.控制符endl 假设显示字符串时,在字符串中包括换行符,而不是在末尾加上endl,这样能够大大降低输入量:假设是要生成一个 ...

  2. STM32 控制步进电机 28BYJ-48

    STM32 控制步进电机 28BYJ-48  http://blog.chinaunix.net/uid-12664992-id-300272.html 步进电机驱动最简化的逻辑: //四相八拍:A- ...

  3. Spring mvc之提交表单

    表单内容: <body> <form action="user/login"> <table> <tr> <td>用户名 ...

  4. boost ini

    #include <boost/property_tree/ptree.hpp>#include <boost/property_tree/ini_parser.hpp> .. ...

  5. sqlserver bak还原

    一.查看: restore filelistonly from disk='F:\Db\A_backup.bak' 二.还原:RESTORE DATABASE AFROM DISK = 'F:\Db\ ...

  6. HBase数据存储格式

    好的数据结构,对于检索数据,插入数据的效率就会很高. 常见的数据结构 B+树 根节点和枝节点非常easy,分别记录每一个叶子节点的最小值,并用一个指针指向叶子节点.  叶子节点里每一个键值都指向真正的 ...

  7. C++学习之路—继承与派生(三):多重继承与虚基类

    (根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 多重继承是指一个派生类有两个或多个基类.例如,有 ...

  8. [置顶] 手把手教你iOS消息推送证书生成以及Push消息

    iOS推送消息是许多iOS应用都具备的功能,今天在给应用加推送功能,在生成证书的过程中,发生了各种令人蛋痛的事.下面就把步骤拿出来分享下: iOS消息推送的工作机制可以简单的用下图来概括: Provi ...

  9. [课堂实践与项目]IOS优先级的计算器

    这个计算器主要是使用数组进行实现的.虽然没有使用前缀后缀表达式,但是是一种方法o. .h文件 // // LCViewController.h // 具有优先级的calculator // // Cr ...

  10. HDU 4870 Rating (2014 多校联合第一场 J)(概率)

    题意: 一个人有两个TC的账号,一开始两个账号rating都是0,然后每次它会选择里面rating较小的一个账号去打比赛,每次比赛有p的概率+1分,有1-p的概率-2分,当然如果本身是<=2分的 ...