《Android提高篇》2.SurfaceView的基本使用

上次介绍MediaPlayer的时候稍微介绍了SurfaceView,Android SurfaceView由于可以直接从内存或者DMA等硬件接口取得图像数据,因此是个非常重要的绘图容器,这次我就用两篇文章来介绍SurfaceView的用法。网上介绍SurfaceView的用法有很多,写法也层出不同,例如继承SurfaceView类,或者继承SurfaceHolder.Callback类等,这个可以根据功能实际需要自己选择,我这里就直接在普通的用户界面调用SurfaceHolder的lockCanvas和unlockCanvasAndPost。

先来看看程序运行的截图:

testSurfaceView

截图1主要演示了直接把正弦波绘画在SurfaceView上

简单绘图 定时器绘图

对比上面的左右两图,右图用.lockCanvas(null),而左图用.lockCanvas(new Rect(oldX, 0, oldX + length, getWindowManager().getDefaultDisplay().getHeight())),对比一下两个效果,由于左图是按指定Rect绘画,所以效率会比右图的全控件绘画高些,并且在清屏之后(canvas.drawColor(Color.BLACK))不会留有上次绘画的残留。

接下来贴出main.xml的源码:

接下来贴出程序源码:

package com.testSurfaceView;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;

public class testSurfaceView extends Activity {
	/** Called when the activity is first created. */
	Button btnSimpleDraw, btnTimerDraw;
	SurfaceView sfv;
	SurfaceHolder sfh;

	private Timer mTimer;
	private MyTimerTask mTimerTask;
	int Y_axis[],// 保存正弦波的Y轴上的点
			centerY,// 中心线
			oldX, oldY,// 上一个XY点
			currentX;// 当前绘制到的X轴上的点

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		btnSimpleDraw = (Button) this.findViewById(R.id.Button01);
		btnTimerDraw = (Button) this.findViewById(R.id.Button02);
		btnSimpleDraw.setOnClickListener(new ClickEvent());
		btnTimerDraw.setOnClickListener(new ClickEvent());
		sfv = (SurfaceView) this.findViewById(R.id.SurfaceView01);
		sfh = sfv.getHolder();

		// 动态绘制正弦波的定时器
		mTimer = new Timer();
		mTimerTask = new MyTimerTask();

		// 初始化y轴数据
		centerY = (getWindowManager().getDefaultDisplay().getHeight() - sfv
				.getTop()) / 2;
		Y_axis = new int[getWindowManager().getDefaultDisplay().getWidth()];
		for (int i = 1; i < y_axis.length;="" i++)="" {//="" 计算正弦波="" y_axis[i="" -="" 1]="centerY" -="" (int)="" (100="" *="" math.sin(i="" *="" 2="" *="" math.pi="" 180));="" }="" }="" class="" clickevent="" implements="" view.onclicklistener="" {="" @override="" public="" void="" onclick(view="" v)="" {="" if="" (v="=" btnsimpledraw)="" {="" simpledraw(y_axis.length="" -="" 1);//="" 直接绘制正弦波="" }="" else="" if="" (v="=" btntimerdraw)="" {="" oldy="centerY;" mtimer.schedule(mtimertask,="" 0,="" 5);//="" 动态绘制正弦波="" }="" }="" }="" class="" mytimertask="" extends="" timertask="" {="" @override="" public="" void="" run()="" {="" simpledraw(currentx);="" currentx++;//="" 往前进="" if="" (currentx="=" y_axis.length="" -="" 1)="" {//="" 如果到了终点,则清屏重来="" cleardraw();="" currentx="0;" oldy="centerY;" }="" }="" }="" *="" *="" 绘制指定区域="" */="" void="" simpledraw(int="" length)="" {="" if="" (length="=" 0)="" oldx="0;" canvas="" canvas="sfh.lockCanvas(new" rect(oldx,="" 0,="" oldx="" +="" length,="" getwindowmanager().getdefaultdisplay().getheight()));//="" 关键:获取画布="" log.i("canvas:",="" string.valueof(oldx)="" +="" ","="" +="" string.valueof(oldx="" +="" length));="" paint="" mpaint="new" paint();="" mpaint.setcolor(color.green);//="" 画笔为绿色="" mpaint.setstrokewidth(2);//="" 设置画笔粗细="" int="" y;="" for="" (int="" i="oldX" +="" 1;="" i="">< length;="" i++)="" {//="" 绘画正弦波="" y="Y_axis[i" -="" 1];="" canvas.drawline(oldx,="" oldy,="" i,="" y,="" mpaint);="" oldx="i;" oldy="y;" }="" sfh.unlockcanvasandpost(canvas);//="" 解锁画布,提交画好的图像="" }="" void="" cleardraw()="" {="" canvas="" canvas="sfh.lockCanvas(null);" canvas.drawcolor(color.black);//="" 清除画布="" sfh.unlockcanvasandpost(canvas);="" }="" }="">

注意一下 for (int i = oldX + 1; i < length; i++) {// 绘画正弦波 这句,在.lockCanvas()指定Rect内减少循环画线的次数,可以提高绘图效率。

暂无评论
  • 1:请一针见血的评论。
  • 2:评论需要审核通过后才能显示。
  • 3:评论字数限制在1000字以内。
  • 当前字数:0
热门文章
推荐文章
随机文章
关于本站 - 广告服务 - 版权声明 - 联系我们 - 友情链接 - 网站地图 - 帮助中心