Android中使用SurfaceView和Canvas來繪製動畫,androidsurfaceview

來源:互聯網
上載者:User

Android中使用SurfaceView和Canvas來繪製動畫,androidsurfaceview

其實每個View中都有Canvas可以用來繪製動畫,只需要在這個View中重載onDraw()方法就可以,但是SurfaceView類是一個專門用來制動動畫的類。


Canvas(中文叫做"畫布")就和HTML5中的canvas標籤一樣可以在一定地區內自由繪製圖形。Canvas+SurfaceView製作的動畫與View Animation和Property Animation這類動畫比起來更加適合大量的集中播放的動畫,比如遊戲畫面、相機的映像顯示等。


因為SurfaceView通常會在另一個專門的線程中不斷重繪介面,所以不像其他動畫那樣要在主線程(UI線程)中播放動畫的同時還要消耗一定的流暢度用來響應使用者輸入。


在使用SurfaceView時需要注意下面這些要點:

1)每個SurfaceView都需要一個SurfaceHolder對象來處理這個SurfaceView的生命週期和擷取這個SurfaceView的Canvas對象,可以通過調用SurfaceView的getHolder()方法來擷取它的SurfaceHolder對象。


2)使用SurfaceView時一般是通過繼承SurfaceView的方式來實現,可以順便implements兩個介面,分別是Runnable和SurfaceHolder.Callback。第二個介面需要重載三個函數,這三個函數就是SurfaceView的生命週期處理了,可以通過SurfaceHolder對象的addCallback()方法把實現好的Callback對象傳進去。


3)在使用SurfaceView的Canvas時一定要記得加鎖同步,因為不能讓畫布同時繪製多個圖案,通過調用這個SurfaceView的SurfaceHolder對象的lockCanvas()就可以做到這一點。繪製完畢後在調用SurfaceHolder對象的unlockCanvasAndPost()方法就可以解鎖並更新。


下面給出了一個用SurfaceView和Canvas繪製動畫的例子,一般直接複製上就可以運行看到效果:

package com.example.canvastest;import android.app.Activity;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.os.Bundle;import android.view.Menu;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.widget.Toast;public class MainActivity extends Activity {/* * 這個類用來當測試的物件,會沿著方形路線持續移動 */class GameObject {private float x;private float y;private Bitmap img;private Paint paint;public GameObject() {this.img = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);this.x = 100;this.y = 100;this.paint = new Paint();}// 在SurfaceView加鎖同步後傳給自己的Canvas上繪製自己public void drawSelf(Canvas canvas) {canvas.drawBitmap(img, x, y, paint);}// 擷取物件下一次要繪製的位置(這裡是沿著一個邊長為400的正方形不斷運動的)public void getNextPos() {if (y == 100 && x != 500)x += 5;else if (x == 500 && y != 500)y += 5;else if (y == 500 && x != 100)x -= 5;else if (x == 100 && y != 100)y -= 5;}}/* * 這個類就是加工了SurfaceView之後的類,所有要運動的物件都最終放在這裡進行繪製 */class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {private Thread thread; // SurfaceView通常需要自己單獨的線程來播放動畫private Canvas canvas;private SurfaceHolder surfaceHolder;private GameObject obj;public MySurfaceView(Context c) {super(c);this.surfaceHolder = this.getHolder();this.surfaceHolder.addCallback(this);this.obj = new GameObject();}@Overridepublic void run() {while (true) {obj.getNextPos();canvas = this.surfaceHolder.lockCanvas(); // 通過lockCanvas加鎖並得到該SurfaceView的畫布canvas.drawColor(Color.BLACK);obj.drawSelf(canvas); // 把SurfaceView的畫布傳給物件,物件會用這個畫布將自己繪製到上面的某個位置this.surfaceHolder.unlockCanvasAndPost(canvas); // 釋放鎖並提交畫布進行重繪try {Thread.sleep(10); // 這個就相當於幀頻了,數值越小畫面就越流暢} catch (Exception e) {e.printStackTrace();}}}@Overridepublic void surfaceDestroyed(SurfaceHolder arg0) {Toast.makeText(getApplicationContext(), "SurfaceView已經銷毀", Toast.LENGTH_LONG).show();}@Overridepublic void surfaceCreated(SurfaceHolder arg0) {Toast.makeText(getApplicationContext(), "SurfaceView已經建立", Toast.LENGTH_LONG).show();this.thread = new Thread(this);this.thread.start();}@Overridepublic void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {// 這裡是SurfaceView發生變化的時候觸發的部分}}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(new MySurfaceView(getApplicationContext())); // 別忘了開始的時候載入我們加工好的的SurfaceView}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}}


如果轉載請註明出處:http://blog.csdn.net/gophers




Android開發裡怎在surfaceView裡給Bitmap對象添加Animation動畫?

留名等答案。沒有用過SurfaceView,不過個人覺得這個問題既然Bitmap不支援SetAnimation功能,樓主就應該換個思路來考慮,不要一條路走到黑。
 
怎擷取SurfaceView中Canvas繪製出的圖片

package src.demo;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.view.SurfaceHolder;import android.view.SurfaceHolder.Callback;import android.view.SurfaceView;public class GameView extends SurfaceView{private Paint paint;private SurfaceHolder sf; public GameView(Context context) { super(context); sf =this.getHolder(); sf.addCallback(new Callback () { public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub } public void surfaceCreated(SurfaceHolder holder) { Canvas canvas = sf.lockCanvas(); paint = new Paint (); paint.setColor(Color.YELLOW); canvas.drawLine(0, 0, 100, 100, paint); sf.unlockCanvasAndPost(canvas); } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub } }); }}
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.