歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android應用實例之跟隨手指的小球——自定義SurfaceView應用

實現的功能:手指在屏幕上滑動,變幻顏色的小球始終跟隨手指移動。

實現的思路:1)自定義SurfaceView,在新線程中每間隔0.1秒就調用一次繪圖方法;2)重寫自定義SurfaceView的onTouchEvent方法,記錄觸屏坐標,用新的坐標重新繪制小球。

關鍵技術點:自定義SurfaceView應用、觸摸事件處理、canvas繪圖、Paint應用

第一步:新建一個工程,命名為BallSurfaceViewDemo,Activity命名為BallActivity。

第二步:編寫自定義SurfaceView類BallSurfaceView,本例中將BallSurfaceView作為BallActivity的內部類,BallActivity代碼如下:

  1. package com.zyg.surfaceview.ball;  
  2.   
  3. import java.util.Random;  
  4.   
  5. import Android.app.Activity;  
  6. import android.content.Context;  
  7. import android.graphics.Canvas;  
  8. import android.graphics.Color;  
  9. import android.graphics.Paint;  
  10. import android.os.Bundle;  
  11. import android.view.MotionEvent;  
  12. import android.view.SurfaceHolder;  
  13. import android.view.SurfaceHolder.Callback;  
  14. import android.view.SurfaceView;  
  15. import android.view.Window;  
  16. import android.view.WindowManager;  
  17.   
  18. public class BallActivity extends Activity {  
  19.     @Override  
  20.     public void onCreate(Bundle savedInstanceState) {  
  21.         super.onCreate(savedInstanceState);  
  22.         //設置全屏   
  23.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  24.         this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
  25.                 WindowManager.LayoutParams.FLAG_FULLSCREEN);  
  26.           
  27.         setContentView(new BallSurfaceView(this));  
  28.     }  
  29.       
  30.     class BallSurfaceView extends SurfaceView implements Callback,Runnable{  
  31.         private int screenW;        //屏幕寬度   
  32.         private int screenH;        //屏幕高度   
  33.         private Paint paint;        //定義畫筆   
  34.         private float cx = 50;      //圓點默認X坐標   
  35.         private float cy = 50;      //圓點默認Y坐標   
  36.         private int radius = 20;  
  37.         //定義顏色數組   
  38.         private int colorArray[] = {Color.BLACK,Color.BLACK,Color.GREEN,Color.YELLOW, Color.RED};  
  39.         private int paintColor = colorArray[0]; //定義畫筆默認顏色   
  40.         private Canvas canvas = null//定義畫布   
  41.         private Thread th = null;     //定義線程   
  42.         private SurfaceHolder sfh = null;  
  43.           
  44.         public BallSurfaceView(Context context){  
  45.             super(context);  
  46.             /*備注1:在此處獲取屏幕高、寬值為0,以為此時view還未被���建, 
  47.              * 在接口Callback的surfaceCreated方法中view才被創建 
  48.              */  
  49.             /*screenW = getWidth(); 
  50.             screenH = getHeight();*/  
  51.               
  52.             //初始化畫筆   
  53.             initPaint();  
  54.             sfh = getHolder();  
  55.             sfh.addCallback(this);  
  56.             th = new Thread(this);  
  57.         }  
  58.           
  59.         @Override  
  60.         public void surfaceCreated(SurfaceHolder holder) {  
  61.             //獲取屏幕寬度   
  62.             screenW = getWidth();  
  63.             //獲取屏幕高度   
  64.             screenH = getHeight();  
  65.             //啟動繪圖線程   
  66.             th.start();  
  67.         }  
  68.           
  69.         private void initPaint(){  
  70.             paint = new Paint();  
  71.             //設置消除鋸齒   
  72.             paint.setAntiAlias(true);  
  73.             //設置畫筆顏色   
  74.             paint.setColor(paintColor);  
  75.         }  
  76.           
  77.         @Override  
  78.         public void run() {  
  79.             while(true){  
  80.                 try{  
  81.                     myDraw();   
  82.                     Thread.sleep(100);  
  83.                 }catch(InterruptedException e){  
  84.                     e.printStackTrace();  
  85.                 }  
  86.             }  
  87.         }  
  88.           
  89.         /*備注2:切記,在自定SurfaceView中定義的myDraw方法,自定義View(繼承自View的子類)中的onDraw方法 
  90.          * 完全是兩碼事: 
  91.          * 1)自定義View(繼承自View的子類)中的onDraw方法是重寫父類的onDraw方法,在調用postInvalidate後會自動回調該onDraw()方法。 
  92.          * 2)此處的myDraw方法需要手動調用,所以此處故意將方法命名為myDraw,突出為該方法是自己寫的,非重寫父類的方法 。 
  93.          *  
  94.          */  
  95.         //重寫onDraw方法實現繪圖操作   
  96.         protected void myDraw() {  
  97.             //獲取canvas實例   
  98.             canvas = sfh.lockCanvas();  
  99.             //將屏幕設置為白色   
  100.             canvas.drawColor(Color.WHITE);  
  101.             //修正圓點坐標   
  102.             revise();  
  103.             //隨機設置畫筆顏色   
  104.             setPaintRandomColor();  
  105.             //繪制小圓作為小球   
  106.             canvas.drawCircle(cx, cy, radius, paint);  
  107.             //將畫好的畫布提交   
  108.             sfh.unlockCanvasAndPost(canvas);  
  109.         }  
  110.           
  111.         //為畫筆設置隨機顏色   
  112.         private void setPaintRandomColor(){  
  113.             Random rand = new Random();  
  114.             int randomIndex = rand.nextInt(colorArray.length);  
  115.             paint.setColor(colorArray[randomIndex]);  
  116.         }  
  117.           
  118.         //修正圓點坐標   
  119.         private void revise(){  
  120.             if(cx <= radius){  
  121.                 cx = radius;  
  122.             }else if(cx >= (screenW-radius)){  
  123.                 cx = screenW-radius;  
  124.             }  
  125.             if(cy <= radius){  
  126.                 cy = radius;  
  127.             }else if(cy >= (screenH-radius)){  
  128.                 cy = screenH-radius;  
  129.             }  
  130.         }  
  131.           
  132.         @Override  
  133.         public boolean onTouchEvent(MotionEvent event) {  
  134.             switch (event.getAction()) {  
  135.             case MotionEvent.ACTION_DOWN:  
  136.                 // 按下   
  137.                 cx = (int) event.getX();  
  138.                 cy = (int) event.getY();  
  139.                 break;  
  140.             case MotionEvent.ACTION_MOVE:  
  141.                 // 移動   
  142.                 cx = (int) event.getX();  
  143.                 cy = (int) event.getY();  
  144.                 break;  
  145.             case MotionEvent.ACTION_UP:  
  146.                 // 抬起   
  147.                 cx = (int) event.getX();  
  148.                 cy = (int) event.getY();  
  149.                 break;  
  150.             }  
  151.               
  152.             /* 
  153.              * 備注1:次處一定要將return super.onTouchEvent(event)修改為return true,原因是: 
  154.              * 1)父類的onTouchEvent(event)方法可能沒有做任何處理,但是返回了false。 
  155.              * 2)一旦返回false,在該方法中再也不會收到MotionEvent.ACTION_MOVE及MotionEvent.ACTION_UP事件。 
  156.              */  
  157.             //return super.onTouchEvent(event);   
  158.             return true;    
  159.         }  
  160.           
  161.         @Override  
  162.         public void surfaceChanged(SurfaceHolder holder, int format, int width,  
  163.                 int height) {  
  164.               
  165.         }  
  166.           
  167.         @Override  
  168.         public void surfaceDestroyed(SurfaceHolder holder) {  
  169.               
  170.         }  
  171.           
  172.     }  
  173. }  
Copyright © Linux教程網 All Rights Reserved