實現的功能:手指在屏幕上滑動,變幻顏色的小球始終跟隨手指移動。
實現的思路:1)自定義SurfaceView,在新線程中每間隔0.1秒就調用一次繪圖方法;2)重寫自定義SurfaceView的onTouchEvent方法,記錄觸屏坐標,用新的坐標重新繪制小球。
關鍵技術點:自定義SurfaceView應用、觸摸事件處理、canvas繪圖、Paint應用
第一步:新建一個工程,命名為BallSurfaceViewDemo,Activity命名為BallActivity。
第二步:編寫自定義SurfaceView類BallSurfaceView,本例中將BallSurfaceView作為BallActivity的內部類,BallActivity代碼如下:
- package com.zyg.surfaceview.ball;
-
- import java.util.Random;
-
- import Android.app.Activity;
- import android.content.Context;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.os.Bundle;
- import android.view.MotionEvent;
- import android.view.SurfaceHolder;
- import android.view.SurfaceHolder.Callback;
- import android.view.SurfaceView;
- import android.view.Window;
- import android.view.WindowManager;
-
- public class BallActivity extends Activity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- //設置全屏
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
- WindowManager.LayoutParams.FLAG_FULLSCREEN);
-
- setContentView(new BallSurfaceView(this));
- }
-
- class BallSurfaceView extends SurfaceView implements Callback,Runnable{
- private int screenW; //屏幕寬度
- private int screenH; //屏幕高度
- private Paint paint; //定義畫筆
- private float cx = 50; //圓點默認X坐標
- private float cy = 50; //圓點默認Y坐標
- private int radius = 20;
- //定義顏色數組
- private int colorArray[] = {Color.BLACK,Color.BLACK,Color.GREEN,Color.YELLOW, Color.RED};
- private int paintColor = colorArray[0]; //定義畫筆默認顏色
- private Canvas canvas = null; //定義畫布
- private Thread th = null; //定義線程
- private SurfaceHolder sfh = null;
-
- public BallSurfaceView(Context context){
- super(context);
- /*備注1:在此處獲取屏幕高、寬值為0,以為此時view還未被���建,
- * 在接口Callback的surfaceCreated方法中view才被創建
- */
- /*screenW = getWidth();
- screenH = getHeight();*/
-
- //初始化畫筆
- initPaint();
- sfh = getHolder();
- sfh.addCallback(this);
- th = new Thread(this);
- }
-
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- //獲取屏幕寬度
- screenW = getWidth();
- //獲取屏幕高度
- screenH = getHeight();
- //啟動繪圖線程
- th.start();
- }
-
- private void initPaint(){
- paint = new Paint();
- //設置消除鋸齒
- paint.setAntiAlias(true);
- //設置畫筆顏色
- paint.setColor(paintColor);
- }
-
- @Override
- public void run() {
- while(true){
- try{
- myDraw();
- Thread.sleep(100);
- }catch(InterruptedException e){
- e.printStackTrace();
- }
- }
- }
-
- /*備注2:切記,在自定SurfaceView中定義的myDraw方法,自定義View(繼承自View的子類)中的onDraw方法
- * 完全是兩碼事:
- * 1)自定義View(繼承自View的子類)中的onDraw方法是重寫父類的onDraw方法,在調用postInvalidate後會自動回調該onDraw()方法。
- * 2)此處的myDraw方法需要手動調用,所以此處故意將方法命名為myDraw,突出為該方法是自己寫的,非重寫父類的方法 。
- *
- */
- //重寫onDraw方法實現繪圖操作
- protected void myDraw() {
- //獲取canvas實例
- canvas = sfh.lockCanvas();
- //將屏幕設置為白色
- canvas.drawColor(Color.WHITE);
- //修正圓點坐標
- revise();
- //隨機設置畫筆顏色
- setPaintRandomColor();
- //繪制小圓作為小球
- canvas.drawCircle(cx, cy, radius, paint);
- //將畫好的畫布提交
- sfh.unlockCanvasAndPost(canvas);
- }
-
- //為畫筆設置隨機顏色
- private void setPaintRandomColor(){
- Random rand = new Random();
- int randomIndex = rand.nextInt(colorArray.length);
- paint.setColor(colorArray[randomIndex]);
- }
-
- //修正圓點坐標
- private void revise(){
- if(cx <= radius){
- cx = radius;
- }else if(cx >= (screenW-radius)){
- cx = screenW-radius;
- }
- if(cy <= radius){
- cy = radius;
- }else if(cy >= (screenH-radius)){
- cy = screenH-radius;
- }
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- // 按下
- cx = (int) event.getX();
- cy = (int) event.getY();
- break;
- case MotionEvent.ACTION_MOVE:
- // 移動
- cx = (int) event.getX();
- cy = (int) event.getY();
- break;
- case MotionEvent.ACTION_UP:
- // 抬起
- cx = (int) event.getX();
- cy = (int) event.getY();
- break;
- }
-
- /*
- * 備注1:次處一定要將return super.onTouchEvent(event)修改為return true,原因是:
- * 1)父類的onTouchEvent(event)方法可能沒有做任何處理,但是返回了false。
- * 2)一旦返回false,在該方法中再也不會收到MotionEvent.ACTION_MOVE及MotionEvent.ACTION_UP事件。
- */
- //return super.onTouchEvent(event);
- return true;
- }
-
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width,
- int height) {
-
- }
-
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
-
- }
-
- }
- }