简介:SurfaceView继承自View,但它与View不同,View是在UI主线程中更新画面,而SurfaceView是在一个新线程中更新画面,View的特性决定了其不适合做动画,因为如果更新画面时间过长,那么UI线程就会被正在画的函数阻塞,所以Android通常用SurfaceView做动画效果。
下面给出一个使用SurfaceView做的简单例子:
package com.yw.myapiupdate.mydraw;import android.app.Activity;import android.os.Bundle;import android.view.Display;/** * * @author yw-tony * */public class MyDrawActivity extends Activity{ private SurfaceViewBall ball ; private int width = 0; private int height = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Display display = getWindowManager().getDefaultDisplay(); width = display.getWidth(); height = display.getHeight(); ball = new SurfaceViewBall(this,width,height); /*ball.setOnTouchListener(new OnTouchListener() { float x = 0; float y = 0; @Override public boolean onTouch(View v, MotionEvent event) { switch(event.getAction()){ case MotionEvent.ACTION_DOWN://按下 ball.drawThread.top += event.getY(); ball.drawThread.left += event.getX(); ball.drawThread.buttom += event.getY(); ball.drawThread.right += event.getX(); break; case MotionEvent.ACTION_MOVE://移动 //基于xy为圆心移动 //得到手指的坐标(x,y) x = event.getRawX(); y = event.getRawY(); x = ((ball.drawThread.right - ball.drawThread.left)/2); y = (ball.drawThread.buttom - ball.drawThread.top)/2; ball.drawThread.top = (int) (event.getRawY()+y); ball.drawThread.left = (int) (event.getRawX()+x); ball.drawThread.right = (int)(200+event.getX()+x); ball.drawThread.buttom = (int)(200+event.getY()+y); log.e("getRawX", ""+event.getRawX()); log.e("getRawY", ""+event.getRawY()); log.e("getX", ""+event.getX()); log.e("getRawY", ""+event.getY()); // ball.drawThread.top += 20;// ball.drawThread.left += event.getRawX();// ball.drawThread.buttom += event.getRawY();// ball.drawThread.right += event.getRawX(); break; case MotionEvent.ACTION_UP://弹起 ball.drawThread.top += 20; ball.drawThread.buttom += 20; ball.drawThread.top += event.getRawY(); ball.drawThread.left += event.getRawX(); ball.drawThread.buttom += event.getRawY(); ball.drawThread.right += event.getRawX(); break; } return true; } });*/ setContentView(ball); } /** * 屏幕触摸事件 */ /*@Override public boolean onTouchEvent(MotionEvent event) { switch(event.getAction()){ case MotionEvent.ACTION_DOWN://按下 ball.drawThread.top += event.getY(); ball.drawThread.left += event.getX(); ball.drawThread.buttom += event.getY(); ball.drawThread.right += event.getX(); break; case MotionEvent.ACTION_MOVE://移动 ball.drawThread.top += event.getRawY();// ball.drawThread.left += event.getRawX();// ball.drawThread.buttom += event.getRawY();// ball.drawThread.right += event.getRawX(); break; case MotionEvent.ACTION_UP://弹起 ball.drawThread.top += event.getRawY(); ball.drawThread.left += event.getRawX(); ball.drawThread.buttom += event.getRawY(); ball.drawThread.right += event.getRawX(); break; } return true; }*/ @Override public void onBackPressed() { ball.drawThread.isRun = false; super.onBackPressed(); }}
MySurfaceView.java
package com.yw.myapiupdate.mydraw;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.view.SurfaceHolder;import android.view.SurfaceView;public class SurfaceViewBall extends SurfaceView implements SurfaceHolder.Callback{ private SurfaceHolder holder; public DrawThread drawThread ; private int width = 0;//屏幕宽度 private int height = 0;//屏幕高度 public SurfaceViewBall(Context context,int width ,int height) { super(context); holder = this.getHolder();//得到surfaceHolder对象 //给holder添加回调函数 holder.addCallback(this); drawThread = new DrawThread(holder); this.width = width; this.height = height; } /** * 当视图发生改变时执行 */ @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } /** * 当创建视图时执行 */ @Override public void surfaceCreated(SurfaceHolder holder) { drawThread.isRun = true; drawThread.start(); } /** * 当视图销毁时执行 */ @Override public void surfaceDestroyed(SurfaceHolder holder) { drawThread.isRun = false; } /** * 绘制图像的线程 * @author yw-tony * */ class DrawThread extends Thread{ private SurfaceHolder drawHolder; public boolean isRun; public int top = 50; public int buttom = 250; public int left = 100; public int right = 300 ; public DrawThread(SurfaceHolder drawHolder){ this.drawHolder = drawHolder; } @Override public void run() { int count = 0; boolean target = false; boolean targetHeightFlag = false; while(isRun){ Canvas canvas = null; try{ synchronized (SurfaceViewBall.class) { canvas = drawHolder.lockCanvas();//锁定画布 canvas.drawColor(Color.BLACK);//设置画布颜色 //创建画笔 Paint paint = new Paint(); paint.setTextSize(20.00f); //设置画笔颜色为白色 paint.setColor(Color.WHITE); //创建矩形区域 /*left = left +20; right = right + 20;*/ /*对矩形左右两边进行碰撞检测*/ if(left <= 0){ //如果碰到左边界,则向右边移动 left = left +20; right = right +20; target = false; }else if(right >= width){ //如果碰到右边界则向左边移动 left = left -20; right = right - 20; target = true; }else{ if(target){ left = left -20; right = right - 20; }else{ left = left +20; right = right + 20; } } /*对矩形上下两边进行碰撞检测*/ if(top<=0){ //如果矩形碰到顶部 top = top+10; buttom = buttom + 10; targetHeightFlag = false; }else if(buttom >= height){ //如果矩形碰到底部 top = top-10; buttom = buttom - 10; targetHeightFlag = true; }else{ //按正常流程执行 if(targetHeightFlag){ top = top-10; buttom = buttom - 10; }else{ top = top+10; buttom = buttom + 10; } } Rect rect = new Rect(left,top,right,buttom); //绘制矩形区域 canvas.drawRect(rect, paint); //绘制字体 canvas.drawText("这是第"+(count++)+"秒", 100, 300, paint); //休眠时间为1秒 if(canvas != null){ holder.unlockCanvasAndPost(canvas);//结束画布锁定,并提交改变 } Thread.sleep(50); } }catch(Exception e){ }finally{ } } } } }