一、对SurfaceView的认识:

在Android中,SurfaceView是View的子类,它内嵌了一个专门用于绘制的Surface,我们可以控制这个Surface的格式和尺寸,Surfaceview控制这个Surface的绘制位置。surface是纵深排序(Z-ordered)的,说明它总在自己所在窗口的后面。SurfaceView提供了一个可见区域,只有在这个可见区域内的surface内容才可见。surface的排版显示受到视图层级关系的影响,它的兄弟视图结点会在顶端显示。这意味者 surface的内容会被它的兄弟视图遮挡,这一特性可以用来放置遮盖物(overlays)(例如,文本和按钮等控件)。注意,如果surface上面有透明控件,那么每次surface变化都会引起框架重新计算它和顶层控件的透明效果,这会影响性能。SurfaceView默认使用双缓冲技术的,它支持在子线程中绘制图像,这样就不会阻塞主线程了,所以它更适合于游戏的开发。

SurfaceView使用的方式与任何View所派生的类都是完全相同的。可以像其他View那样应用动画,并把它们放到布局中。SurfaceView封装的Surface支持所有标准的Canvas方法进行绘图,同时也支持完全的OpenGL ES 库。

二、创建SurfaceView控件:

首先我们需要继承SurfaceView并实现SurfaceHolder.Callback接口,这是因为使用SurfaceView 有一个原则,所有的绘图工作必须得在Surface 被创建之后才能开始(Surface—表面,这个概念在图形编程中常常被提到。基本上我们可以把它当作显存的一个映射,写入到Surface 的内容可以被直接复制到显存从而显示出来,这使得显示速度会非常快),而在Surface 被销毁之前必须结束。所以Callback 中的surfaceCreated 和surfaceDestroyed 就成了绘图处理代码的边界。接着我们需要实现它的3个方法:

1. surfaceCreated(SurfaceHolder holder):surface创建的时候调用,一般在该方法中启动绘图的线程。
2. surfaceChanged(SurfaceHolder holder, int format, int width,int height):surface尺寸发生改变的时候调用,如横竖屏切换。
3. surfaceDestroyed(SurfaceHolder holder) :surface被销毁的时候调用,如退出游戏画面,一般在该方法中停止绘图线程。
同时,我们还需要获得SurfaceHolder,并添加回调函数holder.addCallback(this);,这样这三个方法才会执行。另外,在绘制时,锁定画布,画布用完后要释放holder.unlockCanvasAndPost(canvas);

Android 简单动画的代码:

MainActivity.java

package com.example.cartoon;import android.support.v7.app.ActionBarActivity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;public class MainActivity extends ActionBarActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//实例化SurfaceViewBallSurfaceView sv = new BallSurfaceView(this);setContentView(sv);}}

BallSurfaceView.java

package com.example.cartoon;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.graphics.RectF;import android.util.AttributeSet;import android.view.SurfaceHolder;import android.view.SurfaceView;public class BallSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable{private SurfaceHolder holder;private boolean runFlag;private Paint paint = new Paint();//重写构造方法public BallSurfaceView(Context context) {this(context, null);}public BallSurfaceView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public BallSurfaceView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);//获取Surface句柄对象,通过该对象获取画布holder = this.getHolder();//添加回调接口holder.addCallback(this);//setFocusable(true);}//实现SurfaceHolder.Callback接口的方法@Override//当切换横竖屏时调用public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {}//当SurfaceView创建时调用@Overridepublic void surfaceCreated(SurfaceHolder arg0) {//创建时启动线程runFlag = true;new Thread(this).start();}//当SurfaceView结束时调用@Overridepublic void surfaceDestroyed(SurfaceHolder arg0) {//退出时结束线程runFlag = false;}//重写run方法@Overridepublic void run() {int x = 0;int y = 0;int dx = 2;int dy = 3;int width = 30;int height = 30;while(runFlag){Canvas canvas = null;try {//锁定画笔对象canvas = holder.lockCanvas();//设置画笔paint.setColor(Color.WHITE);paint.setStyle(Paint.Style.FILL);//填充背景颜色Rect rect = new Rect(0, 0, this.getWidth(), this.getHeight());canvas.drawRect(rect, paint);//绘制小球,设置小球颜色为红paint.setColor(Color.RED);RectF rf = new RectF(x, y, x+width, y+height);canvas.drawOval(rf, paint);//小球移动x += dx;y += dy;//边界判断if(x<=0 || x>=this.getWidth()){dx = -dx;}if(y<=0 || y>=this.getHeight()){dy = -dy;}Thread.sleep(40);} catch (InterruptedException e) {e.printStackTrace();}finally{//画布用完要释放if(canvas != null){holder.unlockCanvasAndPost(canvas);}}}}}





更多相关文章

  1. Android之封装好的异步网络请求框架
  2. Android(安卓)序列化对象接口Parcelable使用方法
  3. 调用Android其它Context的Activity
  4. android 获取手机中所有的传感器Sensor类使用方法
  5. android系统图标的使用
  6. Android(安卓)mount/unmount SD卡
  7. Android(安卓)多媒体 -- 四种播放视频的方法
  8. Android中用webView引用js
  9. 原生CountDownTimer 类实现获取验证码的按钮

随机推荐

  1. Google Maps API Key申请方法及地址
  2. 2010.11.27———android 展示网络上的图
  3. Android中的存储路径之外部存储
  4. android studio 3.6.0 绑定视图新特性
  5. ionic1X Could not GET 'https://repo1.m
  6. android Exid 不可修改
  7. Android中Message机制的灵活应用
  8. Android(安卓)App 隐藏显示标题栏、状态
  9. 迈向Android的第一步 - 搭建Android开发
  10. 用Eclipse开发和调试Android应用程序(二)