Android提高第二篇之SurfaceView的基本使用
本文来自http://blog.****.net/hellogv/,引用必须注明出处!
上次介绍MediaPlayer的时候稍微介绍了SurfaceView,SurfaceView由于可以直接从内存或者DMA等硬件接口取得图像数据,因此是个非常重要的绘图容器,这次我就用两篇文章来介绍SurfaceView的用法。网上介绍SurfaceView的用法有很多,写法也层出不同,例如继承SurfaceView类,或者继承SurfaceHolder.Callback类等,这个可以根据功能实际需要自己选择,我这里就直接在普通的用户界面调用SurfaceHolder的lockCanvas和unlockCanvasAndPost。
先来看看程序运行的截图:
截图1主要演示了直接把正弦波绘画在SurfaceView上
对比上面的左右两图,右图用.lockCanvas(null),而左图用.lockCanvas(new
Rect(oldX, 0, oldX + length,
getWindowManager().getDefaultDisplay().getHeight())),对比一下两个效果,由于左图是按指定Rect绘画,所以效率会比右图的全控件绘画高些,并且在清屏之后(canvas.drawColor(Color.BLACK))不会留有上次绘画的残留。
接下来贴出main.xml的源码:
- <?xmlversion="1.0"encoding="utf-8"?>
- <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"android:layout_height="fill_parent"
- android:orientation="vertical">
- <LinearLayoutandroid:id="@+id/LinearLayout01"
- android:layout_width="wrap_content"android:layout_height="wrap_content">
- <Buttonandroid:id="@+id/Button01"android:layout_width="wrap_content"
- android:layout_height="wrap_content"android:text="简单绘画"></Button>
- <Buttonandroid:id="@+id/Button02"android:layout_width="wrap_content"
- android:layout_height="wrap_content"android:text="定时器绘画"></Button>
- </LinearLayout>
- <SurfaceViewandroid:id="@+id/SurfaceView01"
- android:layout_width="fill_parent"android:layout_height="fill_parent"></SurfaceView>
- </LinearLayout>
接下来贴出程序源码:
- packagecom.testSurfaceView;
- importjava.util.Timer;
- importjava.util.TimerTask;
- importandroid.app.Activity;
- importandroid.graphics.Canvas;
- importandroid.graphics.Color;
- importandroid.graphics.Paint;
- importandroid.graphics.Rect;
- importandroid.os.Bundle;
- importandroid.util.Log;
- importandroid.view.SurfaceHolder;
- importandroid.view.SurfaceView;
- importandroid.view.View;
- importandroid.widget.Button;
- publicclasstestSurfaceViewextendsActivity{
- /**Calledwhentheactivityisfirstcreated.*/
- ButtonbtnSimpleDraw,btnTimerDraw;
- SurfaceViewsfv;
- SurfaceHoldersfh;
- privateTimermTimer;
- privateMyTimerTaskmTimerTask;
- intY_axis[],//保存正弦波的Y轴上的点
- centerY,//中心线
- oldX,oldY,//上一个XY点
- currentX;//当前绘制到的X轴上的点
- @Override
- publicvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- btnSimpleDraw=(Button)this.findViewById(R.id.Button01);
- btnTimerDraw=(Button)this.findViewById(R.id.Button02);
- btnSimpleDraw.setOnClickListener(newClickEvent());
- btnTimerDraw.setOnClickListener(newClickEvent());
- sfv=(SurfaceView)this.findViewById(R.id.SurfaceView01);
- sfh=sfv.getHolder();
- //动态绘制正弦波的定时器
- mTimer=newTimer();
- mTimerTask=newMyTimerTask();
- //初始化y轴数据
- centerY=(getWindowManager().getDefaultDisplay().getHeight()-sfv
- .getTop())/2;
- Y_axis=newint[getWindowManager().getDefaultDisplay().getWidth()];
- for(inti=1;i<Y_axis.length;i++){//计算正弦波
- Y_axis[i-1]=centerY
- -(int)(100*Math.sin(i*2*Math.PI/180));
- }
- }
- classClickEventimplementsView.OnClickListener{
- @Override
- publicvoidonClick(Viewv){
- if(v==btnSimpleDraw){
- SimpleDraw(Y_axis.length-1);//直接绘制正弦波
- }elseif(v==btnTimerDraw){
- oldY=centerY;
- mTimer.schedule(mTimerTask,0,5);//动态绘制正弦波
- }
- }
- }
- classMyTimerTaskextendsTimerTask{
- @Override
- publicvoidrun(){
- SimpleDraw(currentX);
- currentX++;//往前进
- if(currentX==Y_axis.length-1){//如果到了终点,则清屏重来
- ClearDraw();
- currentX=0;
- oldY=centerY;
- }
- }
- }
- /*
- *绘制指定区域
- */
- voidSimpleDraw(intlength){
- if(length==0)
- oldX=0;
- Canvascanvas=sfh.lockCanvas(newRect(oldX,0,oldX+length,
- getWindowManager().getDefaultDisplay().getHeight()));//关键:获取画布
- Log.i("Canvas:",
- String.valueOf(oldX)+","+String.valueOf(oldX+length));
- PaintmPaint=newPaint();
- mPaint.setColor(Color.GREEN);//画笔为绿色
- mPaint.setStrokeWidth(2);//设置画笔粗细
- inty;
- for(inti=oldX+1;i<length;i++){//绘画正弦波
- y=Y_axis[i-1];
- canvas.drawLine(oldX,oldY,i,y,mPaint);
- oldX=i;
- oldY=y;
- }
- sfh.unlockCanvasAndPost(canvas);//解锁画布,提交画好的图像
- }
- voidClearDraw(){
- Canvascanvas=sfh.lockCanvas(null);
- canvas.drawColor(Color.BLACK);//清除画布
- sfh.unlockCanvasAndPost(canvas);
- }
- }