Android读书笔记之SurfaceView实现动画

Android读书笔记之SurfaceView实现动画

一.SurfaceView的绘图机制
SurfaceView一般会与SurfaceHolder结合使用,SurfaceHolder用于向与之关联的SurfaceView上绘图,调用SurfaceView的getHolder()方法即可获得SurfaceView关联的SurfaceHolder。
在这里插入图片描述

public class FishView extends SurfaceView
		implements SurfaceHolder.Callback
{
	private SurfaceHolder holder;
	private UpdateViewThread updateThread;
	private boolean hasSurface;
	private Bitmap back;
	private Bitmap[] fishs;
	private int fishIndex = 0; // 定义变量记录绘制第几张鱼的图片
	// 下面定义2个变量,记录鱼的初始位置
	private float fishX = 778;
	private float fishY = 500;
	private float fishSpeed = 6; // 鱼的游动速度
	// 定义鱼游动的角度
	private int fishAngle = new Random().nextInt(60);
	Matrix matrix = new Matrix();
	public FishView(Context ctx, AttributeSet set)
	{
		super(ctx, set);
		// 获取该SurfaceView对应的SurfaceHolder,并将该类的实例作为其Callback
		holder = getHolder();
		holder.addCallback(this);
		hasSurface = false;
		back = BitmapFactory.decodeResource(ctx.getResources()
				, R.drawable.fishbg);
		fishs = new Bitmap[10];
		// 初始化鱼游动动画的10张图片
		for(int i = 0 ; i < 10 ; i++)
		{
			try
			{
				int fishId = (Integer)R.drawable.class
						.getField("fish" + i).get(null);
				fishs[i] = BitmapFactory.decodeResource(
						ctx.getResources(), fishId);
			}
			catch(Exception e){
				e.printStackTrace();
			}
		}
	}

	public void resume()
	{
		// 创建和启动图像更新线程
		if (updateThread == null)
		{
			updateThread = new UpdateViewThread();
			if (hasSurface == true)
				updateThread.start();
		}
	}

	public void pause()
	{
		// 停止图像更新线程
		if (updateThread != null)
		{
			updateThread.requestExitAndWait();
			updateThread = null;
		}
	}

	// 当SurfaceView被创建时回调该方法
	@Override
	public void surfaceCreated(SurfaceHolder holder)
	{
		hasSurface = true;
		resume();
	}

	// 当SurfaceView将要被销毁时回调该方法
	public void surfaceDestroyed(SurfaceHolder holder)
	{
		hasSurface = false;
		pause();
	}

	// 当SurfaceView发生改变时回调该方法
	public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
	{
		if (updateThread != null)
			updateThread.onWindowResize(w, h);
	}

	class UpdateViewThread extends Thread
	{
		// 定义一个记录图形是否更新完成的旗标
		private boolean done;
		UpdateViewThread()
		{
			super();
			done = false;
		}

		@Override
		public void run()
		{
			SurfaceHolder surfaceHolder = holder;
			// 重复绘图循环,直到线程停止
			while (!done)
			{
				// 锁定SurfaceView,并返回到要绘图的Canvas
				Canvas canvas = surfaceHolder.lockCanvas();  // ①
				// 绘制背景图片
				canvas.drawBitmap(back, 0, 0, null);
				// 如果鱼“游出”屏幕之外,重新初始鱼的位置
				if(fishX < 0)
				{
					fishX = 778;
					fishY = 500;
					fishAngle = new Random().nextInt(60);
				}
				if(fishY < 0)
				{
					fishX = 778;
					fishY = 500;
					fishAngle = new Random().nextInt(60);

				}
				// 使用Matrix来控制鱼的旋转角度和位置
				matrix.reset();
				matrix.setRotate(fishAngle);
				matrix.postTranslate(fishX -= fishSpeed * Math
					.cos(Math.toRadians(fishAngle))
					, fishY -= fishSpeed * Math.sin(Math.toRadians(fishAngle)));
				canvas.drawBitmap(fishs[fishIndex++ % fishs.length], matrix, null);
				// 解锁Canvas,并渲染当前图像
				surfaceHolder.unlockCanvasAndPost(canvas);  // ②
				try
				{
					Thread.sleep(60);
				}
				catch (InterruptedException e){}
			}
		}

		public void requestExitAndWait()
		{
			// 把这个线程标记为完成,并合并到主程序线程
			done = true;
			try
			{
				join();
			}
			catch (InterruptedException ex){}
		}

		public void onWindowResize(int w, int h){
			// 处理SurfaceView的大小改变事件
		}
	}

上面的程序使用FishView自身作为SurfaceHolder的Callback实例,并实现了Callback中定义的如下三个方法

void surfaceChanged(SurfaceHolder holder, int format, int width, int height) 当一个SurfaceView的格式或大小发生改变时回调该方法。
void surfaceCreated(SurfaceHolder holder) 当SurfaceView被创建时回调该方法。
void surfaceDestoryed(SurfaceHolder holer) 当SurfaceView将要被销毁时回调该方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值