文章介紹了SurfaceView的用法。網(wǎng)上介紹SurfaceView的用法有很多,寫法也層出不同,例如繼承SurfaceView類,或者繼承SurfaceHolder.Callback類等,這個(gè)可以根據(jù)功能實(shí)際需要自己選擇,我這里就直接在普通的用戶界面調(diào)用SurfaceHolder的lockCanvas和unlockCanvasAndPost。
先來(lái)看看程序運(yùn)行的截圖:

截圖1主要演示了直接把正弦波繪畫在SurfaceView上


對(duì)比上面的左右兩圖,右圖用.lockCanvas(null),而左圖用.lockCanvas(new Rect(oldX, 0, oldX + length,
    getWindowManager().getDefaultDisplay().getHeight())),對(duì)比一下兩個(gè)效果,由于左圖是按指定Rect繪畫,所以效率會(huì)比右圖的全控件繪畫高些,并且在清屏之后(canvas.drawColor(Color.BLACK))不會(huì)留有上次繪畫的殘留。
接下來(lái)貼出main.xml的源碼:
view plaincopy to clipboardprint?
<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="fill_parent" android:layout_height="fill_parent"  
    android:orientation="vertical">  
  
    <LinearLayout android:id="@+id/LinearLayout01"  
        android:layout_width="wrap_content" android:layout_height="wrap_content">  
        <Button android:id="@+id/Button01" android:layout_width="wrap_content"  
            android:layout_height="wrap_content" android:text="簡(jiǎn)單繪畫"></Button>  
        <Button android:id="@+id/Button02" android:layout_width="wrap_content"  
            android:layout_height="wrap_content" android:text="定時(shí)器繪畫"></Button>  
    </LinearLayout>  
    <SurfaceView android:id="@+id/SurfaceView01"  
        android:layout_width="fill_parent" android:layout_height="fill_parent"></SurfaceView>  
</LinearLayout>  
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent" android:layout_height="fill_parent"
 android:orientation="vertical">
 <LinearLayout android:id="@+id/LinearLayout01"
  android:layout_width="wrap_content" android:layout_height="wrap_content">
  <Button android:id="@+id/Button01" android:layout_width="wrap_content"
   android:layout_height="wrap_content" android:text="簡(jiǎn)單繪畫"></Button>
  <Button android:id="@+id/Button02" android:layout_width="wrap_content"
   android:layout_height="wrap_content" android:text="定時(shí)器繪畫"></Button>
 </LinearLayout>
 <SurfaceView android:id="@+id/SurfaceView01"
  android:layout_width="fill_parent" android:layout_height="fill_parent"></SurfaceView>
</LinearLayout>
 
接下來(lái)貼出程序源碼:
view plaincopy to clipboardprint?
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軸上的點(diǎn)   
    centerY,//中心線   
    oldX,oldY,//上一個(gè)XY點(diǎn)    
    currentX;//當(dāng)前繪制到的X軸上的點(diǎn)   
  
    @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();   
  
        //動(dòng)態(tài)繪制正弦波的定時(shí)器   
        mTimer = new Timer();   
        mTimerTask = new MyTimerTask();   
  
        // 初始化y軸數(shù)據(jù)   
        centerY = (getWindowManager().getDefaultDisplay().getHeight() - sfv   
                .getTop()) / 2;   
        Y_axis = new int[getWindowManager().getDefaultDisplay().getWidth()];   
        for (int i = 1; i < Y_axis.length; i++) {// 計(jì)算正弦波   
            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);//動(dòng)態(tài)繪制正弦波   
            }   
  
        }   
  
    }   
  
    class MyTimerTask extends TimerTask {   
        @Override  
        public void run() {   
  
            SimpleDraw(currentX);   
            currentX++;//往前進(jìn)   
            if (currentX == Y_axis.length - 1) {//如果到了終點(diǎn),則清屏重來(lái)   
                ClearDraw();   
                currentX = 0;   
                oldY = centerY;   
            }   
        }   
  
    }   
       
    /*  
     * 繪制指定區(qū)域  
     */  
    void SimpleDraw(int length) {   
        if (length == 0)   
            oldX = 0;   
        Canvas canvas = sfh.lockCanvas(new Rect(oldX, 0, oldX + length,   
                getWindowManager().getDefaultDisplay().getHeight()));// 關(guān)鍵:獲取畫布   
        Log.i("Canvas:",   
                String.valueOf(oldX) + "," + String.valueOf(oldX + length));   
  
        Paint mPaint = new Paint();   
        mPaint.setColor(Color.GREEN);// 畫筆為綠色   
        mPaint.setStrokeWidth(2);// 設(shè)置畫筆粗細(xì)   
  
        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);   
  
    }   
} 
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軸上的點(diǎn)
 centerY,//中心線
 oldX,oldY,//上一個(gè)XY點(diǎn) 
 currentX;//當(dāng)前繪制到的X軸上的點(diǎn)
 @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();
  //動(dòng)態(tài)繪制正弦波的定時(shí)器
  mTimer = new Timer();
  mTimerTask = new MyTimerTask();
  // 初始化y軸數(shù)據(jù)
  centerY = (getWindowManager().getDefaultDisplay().getHeight() - sfv
    .getTop()) / 2;
  Y_axis = new int[getWindowManager().getDefaultDisplay().getWidth()];
  for (int i = 1; i < Y_axis.length; i++) {// 計(jì)算正弦波
   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);//動(dòng)態(tài)繪制正弦波
   }
}
}
 class MyTimerTask extends TimerTask {
  @Override
  public void run() {
   SimpleDraw(currentX);
   currentX++;//往前進(jìn)
   if (currentX == Y_axis.length - 1) {//如果到了終點(diǎn),則清屏重來(lái)
    ClearDraw();
    currentX = 0;
    oldY = centerY;
   }
  }
 }
 
 /*
  * 繪制指定區(qū)域
  */
 void SimpleDraw(int length) {
  if (length == 0)
   oldX = 0;
  Canvas canvas = sfh.lockCanvas(new Rect(oldX, 0, oldX + length,
    getWindowManager().getDefaultDisplay().getHeight()));// 關(guān)鍵:獲取畫布
  Log.i("Canvas:",
    String.valueOf(oldX) + "," + String.valueOf(oldX + length));
  Paint mPaint = new Paint();
  mPaint.setColor(Color.GREEN);// 畫筆為綠色
  mPaint.setStrokeWidth(2);// 設(shè)置畫筆粗細(xì)
  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內(nèi)減少循環(huán)畫線的次數(shù),可以提高繪圖效率。
(審核編輯: 智匯小新)
分享