Android自訂群組件系列【12】——非UI線程繪圖SurfaceView,androidsurfaceview

來源:互聯網
上載者:User

Android自訂群組件系列【12】——非UI線程繪圖SurfaceView,androidsurfaceview
一、SurfaceView的介紹

在前面我們已經會自訂View,使用canvas繪圖,但是View的繪圖機制存在一些缺陷。

1、View缺乏雙緩衝機制。

2、程式必須重繪整個View上顯示的圖片,比較耗資源。

3、非UI線程無法更新View組件,所以會佔用主線程資源,當需要在主線程中處理邏輯的時候會很慢。

在Android中為我們提供了一個SurfaceView來替代View實現繪製圖形,一般在遊戲繪圖方面應用較廣,所以如果是比較複雜的繪圖建議使用SurfaceView.

二、SurfaceView的繪圖機制SurfaceView一般會與SurfaceHolder結合使用,SurfaceHolder用於與之關聯的SurfaceView上繪圖,調用SurfaceView的getHolder()方法可擷取SurfaceView關聯的SurfaceHolder.SurfaceHolder提供了lockCanvas和lockCanvas(Rect dirty)來鎖定繪圖區域,並擷取到該地區的畫布(Canvas)我們通過該畫布就可以進行圖形的繪製了。三、SurfaceView使用執行個體1、一個簡單的使用(繪製在UI線程)
package com.test.surfaceview;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.os.Bundle;import android.view.MotionEvent;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.View;import android.view.View.OnTouchListener;import com.example.testsurfaceview.R;public class MainActivity extends Activity{private SurfaceHolder holder;private Paint paint;private Rect rect;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);paint = new Paint();rect = new Rect();SurfaceView surface = (SurfaceView)findViewById(R.id.show);holder = surface.getHolder();//由系統毀掉的三個函數holder.addCallback(new SurfaceHolder.Callback() {@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {}@Overridepublic void surfaceCreated(SurfaceHolder holder) {Canvas canvas = holder.lockCanvas();Bitmap bitmap = BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.ic_launcher);canvas.drawBitmap(bitmap, 0, 0, null);holder.unlockCanvasAndPost(canvas);}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {}});//綁定事件監聽surface.setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {if(event.getAction() == MotionEvent.ACTION_DOWN){int cx = (int)event.getX();int cy = (int)event.getY();rect.set(cx - 50, cy - 50, cx + 50, cy + 50);//鎖定一個固定地區並鎖定Canvas canvas = holder.lockCanvas(rect);//儲存畫布目前狀態canvas.save();//旋轉畫布canvas.rotate(30, cx, cy);paint.setColor(Color.RED);//繪製方塊canvas.drawRect(cx - 40, cy - 40, cx, cy, paint);//恢複畫布canvas.restore();paint.setColor(Color.GREEN);//繪製方塊canvas.drawRect(cx, cy, cx + 40, cy + 40, paint);//繪製完成,釋放畫布,提交修改holder.unlockCanvasAndPost(canvas);}return false;}});}}
2、在非UI線程中繪製
package com.test.surfaceview;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.graphics.Rect;import android.os.AsyncTask;import android.util.AttributeSet;import android.view.SurfaceHolder;import android.view.SurfaceView;import com.example.testsurfaceview.R;/** * 陽光小強 http://blog.csdn.net/dawanganban *  * @author Administrator *  */public class MySurfaceView extends SurfaceView {private Context context;private Rect rect;private Paint paint;private AppStartDrawView appStartDrawView;public MySurfaceView(Context context, AttributeSet attrs) {super(context, attrs);this.context = context;rect = new Rect();paint = new Paint();appStartDrawView = new AppStartDrawView();this.getHolder().addCallback(appStartDrawView);}/** * 停止動畫 */public void stopAnim() {appStartDrawView.cancel(true);}private class AppStartDrawView extends AsyncTask<Void, Integer, Void> implements SurfaceHolder.Callback {private boolean isStarted = false;private SurfaceHolder holder;@Overridepublic void surfaceCreated(SurfaceHolder holder) {this.holder = holder;//繪製一個圖片Canvas canvas = holder.lockCanvas();Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher);canvas.drawBitmap(bitmap, 0, 0, null);holder.unlockCanvasAndPost(canvas);if (!isStarted) {this.execute();isStarted = true;}}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {this.holder = holder;}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {isStarted = false;holder = null;}@Overrideprotected Void doInBackground(Void... params) {int cx = 0;int cy = 0;while(!isCancelled()){//繪製動畫//TODO .....rect.set(cx - 50, cy - 50, cx + 50, cy + 50);//鎖定一個固定地區並鎖定Canvas canvas = holder.lockCanvas(rect);//儲存畫布目前狀態canvas.save();//旋轉畫布canvas.rotate(30, cx, cy);paint.setColor(Color.RED);//繪製方塊canvas.drawRect(cx - 40, cy - 40, cx, cy, paint);//恢複畫布canvas.restore();paint.setColor(Color.GREEN);//繪製方塊canvas.drawRect(cx, cy, cx + 40, cy + 40, paint);//繪製完成,釋放畫布,提交修改holder.unlockCanvasAndPost(canvas);//TODO ....try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}cx += 60;cy += 60;if(cx  >= 400){stopAnim();}}return null;}}}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.