使用SurfaceView即時畫圖

本文來自人人網android開發交流羣


大家常撰寫View的子類別,然後在其onDraw()函數裏繪出各式各樣的圖形,例如畫出點或是直線。不過,基本上onDraw()函數是在Canvas畫完所有線條等圖形後,才一塊兒將Canvas顯示出來。
然而,當我們想再畫出一些線條之後,停個幾秒鐘之後,才繼續繪出後續的圖形,這種有停頓的計時性繪圖,又該如何呢?
例如,先繪出一條綠色線段:

(圖)高煥堂講義之十五:如何使用SurfaceView計時繪點或線

停頓5秒鐘之後,才畫出一條黃色線段:

(圖)高煥堂講義之十五:如何使用SurfaceView計時繪點或線

這時,使用SurfaceView會是一個好方法。

SurfaceView類是一個特別的View子類,在遊戲中經常被使用,速度要比一般的View快幾倍。

它和View類的主要區別在於它的描繪工作在輔助線程中完成,不佔用主線程;而普通View類的描繪在主線程中完成。

需要實現SurfaceHolder.Callback接口,以對其進行創建,銷燬,改變時的情況進行監視。

如下之範例程序代碼:

 package com.misoo.ppvv;   
 import android.app.Activity;   
 import android.os.Bundle;   
 import android.widget.LinearLayout;   
   
 public class ac01 extends Activity {   
     @Override  
     protected void onCreate(Bundle icicle) {   
         super.onCreate(icicle);   
         MySurfaceView mv = null;   
         try {   
             mv = new MySurfaceView(this);   
         } catch (InterruptedException e) {   
             e.printStackTrace();   
         }   
         //----------------------------------   
         LinearLayout layout = new LinearLayout(this);   
         layout.setOrientation(LinearLayout.VERTICAL);   
         LinearLayout.LayoutParams param =    
             new LinearLayout.LayoutParams(200, 150);   
         param.topMargin = 5;   
         layout.addView(mv, param);   
         //----------------------------------------     
         setContentView(layout);   
     }   
 }   
   
   
  
 package com.misoo.ppvv;   
 import android.content.Context;   
 import android.graphics.Color;   
 import android.view.SurfaceHolder;   
 import android.view.SurfaceView;   
   
 class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {   
     SurfaceHolder mHolder;   
     private DrawThread mThread;   
    private dwList dwl;     
        
     MySurfaceView(Context context) throws InterruptedException {   
         super(context);   
         getHolder().addCallback(this);   
            
         dwl = new dwList();   
         dwl.begin_record();   
        dwl.record(30, 30, 0, 0);   
         dwl.record(100, 100, 1, Color.GREEN);   
        Thread.sleep(50);   
         dwl.record(100, 30, 1, Color.YELLOW);   
         Thread.sleep(60);   
         dwl.record(30, 30, 1, Color.BLUE);   
         Thread.sleep(40);   
         dwl.record(30, 100, 1, Color.RED);   
     }   
    public void surfaceCreated(SurfaceHolder holder) {   
         mHolder = holder;   
         mThread = new DrawThread();   
         mThread.start();   
      }   
    public void surfaceDestroyed(SurfaceHolder holder) {   
       mThread = null;   
     }   
    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {   
    }   
    // ----------------------------------------------------------------------   
    class DrawThread extends Thread {   
         DrawThread() {   
             super();   
         }   
         @Override  
         public void run() {   
            dwl.draw(mHolder);   
          }   
       }   
 }      
 
  
   
 package com.misoo.ppvv;   
 import java.util.ArrayList;   
 import java.util.Iterator;   
 import android.graphics.Canvas;   
 import android.graphics.Paint;   
 import android.view.SurfaceHolder;   
   
 public class dwList {   
     private Paint paint= null;   
     private long draw_time;   
     private ArrayList<dwPoint> poList;   
        
   public void begin_record()   
     {     
         dwPoint.initial_time  = System.currentTimeMillis();   
         poList.clear();    
     }   
   public void record(int x, int y, int ty, int color)   
     {    dwPoint po = new dwPoint(x, y, ty, color);   
          poList.add(po);      
     }   
   public dwList(){   
         paint = new Paint();   
         poList = new ArrayList<dwPoint>();   
     }   
   public void draw(SurfaceHolder holder) {   
         dwPoint po;   
         long curr_time;        
         long base_time =0;         
         int nnn = 0;   
         Iterator<dwPoint> it = poList.iterator();   
         while (it.hasNext() ){   
            po = it.next();   
            draw_time = po.m_timeSpan * 100;   
            if(nnn == 0)      
                base_time = System.currentTimeMillis();   
            nnn++;   
            //---------   waiting ----------------------------------   
             do {      
                 curr_time =  System.currentTimeMillis() - base_time;        
                 }     
             while (curr_time < draw_time);   
             //------------------------------------------------------           
             paint(holder, nnn );   
         }   
     }   
     public void paint(SurfaceHolder holder, int k) {   
         Canvas canvas = holder.lockCanvas();   
         dwPoint po;        
         int lastX = 0;   
         int lastY = 0;   
            
         Iterator<dwPoint> it = poList.iterator();   
         for (int i = 0; i<k; i++) {   
            po = it.next();   
            if(po.m_type == 0 )  {     
                lastX = po.m_x;     
                lastY = po.m_y;    
                }   
            else  {     
                paint.setColor(po.m_color);    
                paint.setStrokeWidth(3);   
                canvas.drawLine(lastX, lastY, po.m_x, po.m_y, paint);   
                lastX = po.m_x;       
                lastY = po.m_y;     
                }   
          }   
            
         holder.unlockCanvasAndPost(canvas);   
      }   
 }   
   
   
   
 package com.misoo.ppvv;   
   
 public class dwPoint {   
      public static long initial_time;   
      public int m_x, m_y, m_type;   
      public long m_timeSpan;   
      public int m_color;   
      public dwPoint() {}   
      public dwPoint(int x, int y, int ty, int cc) {   
          m_x = x;    
          m_y = y;    
          m_type = ty;    
          m_color = cc;   
          m_timeSpan = (long)(System.currentTimeMillis() - initial_time);   
   }  


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章