本文實例為大家分享了使用SurfaceView實現動畫的具體代碼,供大家參考,具體內容如下
與自定義view繪圖進行對比:
1.view繪圖沒有雙緩沖機制,而surfaceview有
2.view繪圖更新時,要全部更新整張圖片,而surfaceview可以更新部分區域
3.新線程無法直接更新view繪圖,需要handler配合。
魚兒游動的動畫:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <com.example.liuyan.testbutfly.FishView android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
java代碼:
public class FishView extends SurfaceView implements SurfaceHolder.Callback{  private SurfaceHolder holder;  private UpdateViewThread updatethread;  private boolean hasSurface;  private Bitmap back;  private Bitmap[] fishs;  private int fishIndex = 0;//繪制第幾張魚  //魚的初始位置  private float fishx = 778;  private float fishy = 500;  private float fishSpeed = 6; //魚的游動速度  //魚的游動角度  private int fishAngle = new Random().nextInt(60);  Matrix matrix = new Matrix();   public FishView(Context context) {   super(context);   Log.i("mydate" , "開始");   //獲取surfaceview的surfaceholder,并將該類的實例作為其callback   holder = getHolder();   holder.addCallback(this);//以自身作為callback,回調方法   hasSurface = false;   back = BitmapFactory.decodeResource(context.getResources() , R.drawable.fishbg);//背景   int[] id = new int[]{R.drawable.fish0 , R.drawable.fish1 , R.drawable.fish2 ,R.drawable.fish3 ,R.drawable.fish4 ,R.drawable.fish5 ,R.drawable.fish6 ,R.drawable.fish7 ,R.drawable.fish8, R.drawable.fish9};   fishs = new Bitmap[10];   //初始化 魚游動的10張圖   for (int i = 0 ; i < 10 ; i++){    try {     fishs[i] = BitmapFactory.decodeResource(context.getResources() , id[i]);    } catch (Exception e){     e.printStackTrace();    }   }   Log.i("mydate" , "結束");  }   public FishView(Context context, AttributeSet attrs) {   super(context, attrs);   Log.i("mydate" , "開始");   //獲取surfaceview的surfaceholder,并將該類的實例作為其callback   holder = getHolder();   holder.addCallback(this);//以自身作為callback,回調方法   hasSurface = false;   back = BitmapFactory.decodeResource(context.getResources() , R.drawable.fishbg);//背景   int[] id = new int[]{R.drawable.fish0 , R.drawable.fish1 , R.drawable.fish2 ,R.drawable.fish3 ,R.drawable.fish4 ,R.drawable.fish5 ,R.drawable.fish6 ,R.drawable.fish7 ,R.drawable.fish8, R.drawable.fish9};   fishs = new Bitmap[10];   //初始化 魚游動的10張圖   for (int i = 0 ; i < 10 ; i++){    try { //    int fishId = (Integer) R.drawable.class.getField("fish" + i).get(null);//反射機制獲取圖片 //    Log.i("mydate" , " "+ fishId);     fishs[i] = BitmapFactory.decodeResource(context.getResources() , id[i]);    } catch (Exception e){     e.printStackTrace();    }   }   Log.i("mydate" , "結束");  }    public void resume(){   //創建和啟動 圖片更新線程   if (updatethread == null){    updatethread = new UpdateViewThread();    if (hasSurface == true){     updatethread.start();    }   }  }   public void pause(){   //停止 圖像更新線程   if (updatethread != null){    updatethread.requestExitAndWait();    updatethread = null;   }  }    @Override  public void surfaceCreated(SurfaceHolder holder) { //surfaceview被創建時回調該方法   hasSurface = true;   resume(); //開啟線程更新  }   @Override  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {//surfaceview改變時回調該方法   if (updatethread != null){    updatethread.onWindowResize(width , height);   }  }   @Override  public void surfaceDestroyed(SurfaceHolder holder) {//surfaceview銷毀時回調該方法   hasSurface = false;   pause(); //停止線程更新  }   class UpdateViewThread extends Thread{   //定義圖像是否更新完成的標志   private boolean done;    public UpdateViewThread() {    super();    done = false;   }    @Override   public void run() {    SurfaceHolder surfaceholder = holder;    //循環繪制,直到線程停止    while (!done){     Canvas canvas = surfaceholder.lockCanvas();//鎖定surfaceview,準備繪制     //繪制背景     canvas.drawBitmap(back , 0 , 0 , null);     //魚游出屏幕外,重新初始化魚的位置     if (fishx < 0 ){      fishx = 778;      fishy = 500;      fishAngle = new Random().nextInt(60);     }     if (fishy < 0){      fishx = 778;      fishy = 500;      fishAngle = new Random().nextInt(60);     }     //用matrix控制魚的旋轉角度和位置     matrix.reset();     matrix.setRotate(fishAngle);//下面的位置計算看圖片的解釋如下:     matrix.postTranslate(fishx -= fishSpeed * Math.cos(Math.toRadians(fishAngle)) , fishy -= fishSpeed * Math.sin(Math.toRadians(fishAngle)));     canvas.drawBitmap(fishs[fishIndex++%fishs.length] , matrix , null);     surfaceholder.unlockCanvasAndPost(canvas);//解鎖canvas,渲染繪制圖像     try {      Thread.sleep(60);     } catch (Exception e){      e.printStackTrace();     }    }   }    public void requestExitAndWait() {    //將繪制線程 標記為完成 ,并合并到主線程中    done = true;    try {     join();    } catch (Exception e){     e.printStackTrace();    }   }    public void onWindowResize(int width, int height) {    //處理surfaceview的大小改變事件   }  }  } 位置計算圖片解釋如下:
Math.toRadians(fishAngle)
先理解這句代碼的意思:將0-360的角度制角度轉化為pi弧度制角度
	
魚兒不停的游動,坐標改變其實就是:
當前的x坐標 - 速度*cos角度 , 當前的y坐標 - 速度*sin角度
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。
新聞熱點
疑難解答