android surfaceView 的簡單使用 畫圖,拖動效果


前面說到了畫圖,其實更好的就是使用 surfaceView了。

surfaceView 繼承於 View,View里面嵌套了一個專門用於畫圖的 surface,

對於一個View的onDraw()方法,不能夠滿足將其移動到后台線程中去。因為從后台線程修改一個GUI元素會被顯式地禁止的。當需要快速地更新View的UI,或者當前渲染代碼阻塞GUI線程的時間過長的時候,SurfaceView就是解決上述問題的最佳選擇。SurfaceView封裝了一個Surface對象,而不是Canvas。這一點很重要,因為Surface可以使用后台線程繪制。對於那些資源敏感的操作,或者那些要求快速更新或者高速幀率的地方,例如使用3D圖形,創建游戲,或者實時預覽攝像頭,這一點特別有用。

可以直接從內存或硬件設備比如相機等取得圖像數據,是個非常重要的繪圖容器。它的特性是:可以在主線程之外的線程中向屏幕繪圖。這樣可以避免畫圖任務繁重的時候造成主線程阻塞,從而提高了程序的反應速度。繪制的東西直接復制到顯存從而顯示出來,這使得顯示速度會非常快,而在Surface 被銷毀之前必須結束。

 

下面給個簡單的例子,就是不停的繪制 ,這樣按照前面說的,就可以再 上面繪制各種自己想要的效果了:

 

 
  1. public class SurfaceDraw  extends Activity{  
  2.      private SurfaceView    sf;      
  3.      private SurfaceHolder  sfh;   //surfaceView的 控制器  
  4.       
  5.     @Override  
  6.     protected void onCreate(Bundle savedInstanceState) {  
  7.         // TODO Auto-generated method stub  
  8.         super.onCreate(savedInstanceState);  
  9.         setContentView(R.layout.activity_draw);  
  10.         sf = (SurfaceView) this.findViewById(R.id.SurfaceView01);  
  11.         //得到控制器  
  12.         sfh = sf.getHolder();  
  13.         //對 surfaceView 進行操作  
  14.         sfh.addCallback(new DoThings());// 自動運行surfaceCreated以及surfaceChanged  
  15.     }  
  16.       
  17.       
  18.     private class DoThings implements SurfaceHolder.Callback{  
  19.         @Override  
  20.         public void surfaceChanged(SurfaceHolder holder, int format, int width,  
  21.                 int height) {  
  22.             //在surface的大小發生改變時激發  
  23.             System.out.println("surfaceChanged");  
  24.         }  
  25.   
  26.         @Override  
  27.         public void surfaceCreated(SurfaceHolder holder){  
  28.             new Thread(){  
  29.                 public void run() {  
  30.                     while(true){  
  31.                         //1.這里就是核心了, 得到畫布 ,然后在你的畫布上畫出要顯示的內容  
  32.                         Canvas c = sfh.lockCanvas(new Rect(00200200));  
  33.                         //2.開畫  
  34.                         Paint  p =new Paint();  
  35.                         p.setColor(Color.rgb( (int)(Math.random() * 255),   
  36.                                 (int)(Math.random() * 255) ,  (int)(Math.random() * 255)));  
  37.                         Rect aa  =  new Rect( (int)(Math.random() * 100) ,  
  38.                                 (int)(Math.random() * 100)   
  39.                                 ,(int)(Math.random() * 500)   
  40.                                 ,(int)(Math.random() * 500) );  
  41.                         c.drawRect(aa, p);  
  42.                         //3. 解鎖畫布   更新提交屏幕顯示內容  
  43.                         sfh.unlockCanvasAndPost(c);  
  44.                         try {  
  45.                             Thread.sleep(1000);  
  46.                               
  47.                         } catch (Exception e) {  
  48.                         }  
  49.                     }  
  50.                 };  
  51.             }.start();  
  52.               
  53.         }  
  54.   
  55.         @Override  
  56.         public void surfaceDestroyed(SurfaceHolder holder) {  
  57.                //銷毀時激發,一般在這里將畫圖的線程停止、釋放。  
  58.             System.out.println("surfaceDestroyed==");     
  59.         }     
  60.     }  
  61. }  

// 實現拖拽效果,也就是動態的繪制

 
  1. public class Drag extends Activity {  
  2.       
  3.     @Override  
  4.     protected void onCreate(Bundle savedInstanceState) {  
  5.             super.onCreate(savedInstanceState);   
  6.             DragImage view=new DragImage(this);   
  7.             setContentView(view);   
  8.     }  
  9.       
  10. private class DragImage extends SurfaceView implements SurfaceHolder.Callback,Runnable,OnTouchListener{  
  11.         private Context context;  
  12.         private SurfaceHolder holder;  
  13.         private Bitmap icon;  
  14.         private Paint paint;  
  15.         private boolean running=true;  
  16.   
  17.         public DragImage(Context context) {  
  18.             super(context);  
  19.             this.context=context;  
  20.             holder = this.getHolder();//獲取holder    
  21.             holder.addCallback(this);  
  22.             this.setOnTouchListener(this);           
  23.         }  
  24.           
  25.         @Override  
  26.         public void surfaceCreated(SurfaceHolder holder) {  
  27.               
  28.             icon = BitmapFactory.decodeResource(context.getResources(),R.drawable.wuranl_1);    
  29.             paint=new Paint();  
  30.             running=true;  
  31.             new Thread(this).start();  
  32.               
  33.         }  
  34.   
  35.         @Override  
  36.         public void surfaceChanged(SurfaceHolder holder, int format, int width,  
  37.                 int height) {  
  38.         }  
  39.           
  40.           
  41.         @Override  
  42.         public void surfaceDestroyed(SurfaceHolder holder) {  
  43.             running=false;  
  44.         }  
  45.           
  46.         @Override  
  47.         public void run() {   
  48.             int SLEEP_TIME=100;  
  49.             while (running) {  
  50.                 //開始畫的時間    long start=System.currentTimeMillis();  
  51.                  Canvas canvas = holder.lockCanvas();//獲取畫布   
  52.                  canvas.drawColor(Color.BLACK);  
  53.                  canvas.drawBitmap(icon, rect.left,rect.top,null);  
  54.                  holder.unlockCanvasAndPost(canvas);// 解鎖畫布,提交畫好的圖像    
  55.                 //結束的時間   long end=System.currentTimeMillis();    
  56.             }  
  57.         }  
  58.   
  59. //      Region region=new Region();  
  60.         private Point point=new Point();//點擊點  
  61.         private Rect rect;//圖片的rect  
  62.         private boolean canDrag=false;//判斷是否點擊在圖片上,否則拖動無效  
  63.         private int offsetX=0,offsetY=0;//點擊點離圖片左上角的距離  
  64.         @Override  
  65.         public boolean onTouch(View v, MotionEvent event) {  
  66.             // TODO Auto-generated method stub  
  67.             switch (event.getAction()) {  
  68.               
  69.             //手按下的時候  
  70.             case MotionEvent.ACTION_DOWN:  
  71.                 point.x=(int)event.getX();  
  72.                 point.y=(int)event.getY();  
  73.                 if(rect.contains(point.x, point.y)){  
  74.                     canDrag=true;  
  75.                     offsetX=point.x-rect.left;  
  76.                     offsetY=point.y-rect.top;  
  77.                 }  
  78.                 break;  
  79.               
  80.             //移動的時候  
  81.             case MotionEvent.ACTION_MOVE:  
  82.                 if(canDrag){  
  83.                     rect.left=(int)event.getX()-offsetX;  
  84.                     rect.top=(int)event.getY()-offsetY;  
  85.                     rect.right=rect.left+icon.getWidth();  
  86.                     rect.bottom=rect.top+icon.getHeight();  
  87.                     if (rect.left < 0) {    
  88.                         rect.left = 0;  
  89.                         rect.right =  rect.left+icon.getWidth();  
  90.                     }    
  91.                     if (rect.right >  getMeasuredWidth()) {    
  92.                         rect.right =  getMeasuredWidth();  
  93.                         rect.left = rect.right-icon.getWidth();  
  94.                     }    
  95.                     if (rect.top < 0) {  
  96.                         rect.top = 0;  
  97.                         rect.bottom = rect.top+icon.getHeight();  
  98.                     }    
  99.                     if (rect.bottom > getMeasuredHeight()) {  
  100.                         rect.bottom = getMeasuredHeight();  
  101.                         rect.top = rect.bottom-icon.getHeight();  
  102.                     }  
  103.                 }  
  104.                 break;  
  105.             case MotionEvent.ACTION_UP:  
  106.                 canDrag=false;  
  107.                 break;  
  108.   
  109.             default:  
  110.                 break;  
  111.             }  
  112.             return true;  
  113.         }  
  114.   
  115.     }  
  116. }  


還有前面在 View上面繪制的動態折線圖,在surfaceView上效果也更好呢


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM