使用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);   
   }  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值