1. 程式人生 > >Android學習之旅(第一篇) SurfaceView的原理以及使用場景

Android學習之旅(第一篇) SurfaceView的原理以及使用場景

為什麼要使用SurfaceView來實現動畫?

因為View的繪圖存在以下缺陷:

  1. View缺乏雙緩衝機制
  2. 當程式需要更新View上的影象時,程式必須重繪View上顯示的整張圖片
  3. 新執行緒無法直接更新View元件

SurfaceView的繪圖機制

  • 一般會與SurfaceView結合使用
  • 呼叫SurfaceView的getHolder()方法即可獲得SurfaceView關聯的SurfaceHolder

SurfaceHolder提供瞭如下方法來獲取Canvas物件

  1. Canvas lockCanvas():鎖定整個SurfaceView物件,獲取該Surface上的Canvas
  2. Canvas lockCanvas(Rect dirty):鎖定SurfaceView上Rect劃分的區域,獲取該Surface上的Canvas
  3. unlockCanvasAndPost(canvas):釋放繪圖、提交所繪製的圖形,需要注意,當呼叫SurfaceHolder上的unlockCanvasAndPost方法之後,該方法之前所繪製的圖形還處於緩衝之中,下一次lockCanvas()方法鎖定的區域可能會“遮擋”它

“`

public class SurfaceViewTest extends Activity

{
// SurfaceHolder負責維護SurfaceView上繪製的內容
private SurfaceHolder holder;
private Paint paint;

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    paint = new Paint();
    SurfaceView surface = (SurfaceView) findViewById(R.id.show);
    // 初始化SurfaceHolder物件
    holder = surface.getHolder();
    holder.addCallback(new Callback()
    {
        @Override
        public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,
                int arg3)
        {
        }

        @Override
        public void surfaceCreated(SurfaceHolder holder)
        {
            // 鎖定整個SurfaceView
            Canvas canvas = holder.lockCanvas();
            // 繪製背景
            Bitmap back = BitmapFactory.decodeResource(
                SurfaceViewTest.this.getResources()
                , R.drawable.sun);
            // 繪製背景
            canvas.drawBitmap(back, 0, 0, null);
            // 繪製完成,釋放畫布,提交修改
            holder.unlockCanvasAndPost(canvas);
            // 重新鎖一次,"持久化"上次所繪製的內容
            holder.lockCanvas(new Rect(0, 0, 0, 0));
            holder.unlockCanvasAndPost(canvas);
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder)
        {
        }
    });
    // 為surface的觸控事件繫結監聽器
    surface.setOnTouchListener(new OnTouchListener()
    {
        @Override
        public boolean onTouch(View source, MotionEvent event)
        {
            // 只處理按下事件
            if (event.getAction() == MotionEvent.ACTION_DOWN)
            {
                int cx = (int) event.getX();
                int cy = (int) event.getY();
                // 鎖定SurfaceView的區域性區域,只更新區域性內容
                Canvas canvas = holder.lockCanvas(new Rect(cx - 50,
                        cy - 50, cx + 50, cy + 50));
                // 儲存canvas的當前狀態
                canvas.save();
                // 旋轉畫布
                canvas.rotate(30, cx, cy);
                paint.setColor(Color.RED);
                // 繪製紅色方塊
                canvas.drawRect(cx - 40, cy - 40, cx, cy, paint);
                // 恢復Canvas之前的儲存狀態
                canvas.restore();
                paint.setColor(Color.GREEN);
                // 繪製綠色方塊
                canvas.drawRect(cx, cy, cx + 40, cy + 40, paint);
                // 繪製完成,釋放畫布,提交修改
                holder.unlockCanvasAndPost(canvas);
            }
            return false;
        }
    });
}
}

“`

上面的程式為SurfaceHolder添加了一個CallBack例項,該Callback中定義瞭如下三個方法:

  • void surfaceChanged(SurfaceHolder holder, int format, int width, int height):當一個surface的格式或大小發生改變時回撥該方法。
  • void surfaceCreated(SurfaceHolder holder):當surface被建立時回撥該方法
  • void surfaceDestroyed(SurfaceHolder holder):當surface將要被銷燬時回撥該方法

相關推薦

Android學習第一 SurfaceView原理以及使用場景

為什麼要使用SurfaceView來實現動畫? 因為View的繪圖存在以下缺陷: View缺乏雙緩衝機制 當程式需要更新View上的影象時,程式必須重繪View上顯示的整張圖片 新執行緒無法直接更新View元件 SurfaceView的繪圖機制

21000+行原生J S的學習第一

原生js的學習之路學習JS已經有一年多了(小白),看了很多書,也寫了不少代碼,但是總感覺功力還是不夠(哈哈),前段時間偶然接觸到原生JS代碼,邊對此產生了興趣,學習原生JS對於我們深入了解js有很好的幫助比如函數的參數類型、返回值類型等。下來先介紹一下原生JS的語法結構,來幫助大家更好的學習和閱讀原生JS:d

Android的DatePicker和TimePicker-android學習三十八

cursor ini lis drawable textview @+ type pin view DatePicker和TimePicker簡單介紹 DatePicker和TimePicker是從FrameLayout繼承而來。他們都是比較簡單的組件

Android的SeekBar和RateBar的使用-android學習三十二

SeekBar簡介 SeekBar允許使用者拖動,進行調節經常用於音量調節等方面。 android:thumb設定drawable物件來表示拖動的物體。 setOnSeekBarChangeLis

SimpleAdapter和Baseadapter填充listActivity-android學習

簡介 SimpleAdapter的功能是能夠為AbsListView提供複雜的資料,需要構造ListView 程式碼示例 package peng.liu.testview; import android.app.Activity; import a

Android日曆檢視CalendarView講解-android學習三十六

CalendarView簡介 CalendarView用於顯示和選擇日期,如果希望監聽事件的改變可以用setOnDateChangeListener()方法。 CalendarView屬性介紹

Android的stateListDrawable,layerDawable,clipdrawable,AnimationDarwable介紹-android學習五十五

StatelistDrawable資源 程式碼示例 <?xml version="1.0" encoding="utf-8"?> <selector xmlns:a

python學習基礎——列表,字典,集合

cef mes 所有 聽說 基本 變量 .so tdi 作用 一、列表,元組操作 定義列表 names = [‘Alex‘,"Tenglan",‘Eric‘] 查看 >>> names[0] ‘Alex‘ >>> names[2]

python學習基礎——函數

pri inux 形參 定義變量 dev 函數計算 學生 span 指定 一、簡單介紹 三種編程: 面向對象 class 面向過程 def 函數式編程 def 過程是沒有返回值的函數 定義: 函數是指將一組語句的集合通過一個名字(函數名)封裝起來,

Python學習十一

Python基礎知識(10):函式(Ⅱ) 一、全域性變數和區域性變數 區域性變數:在函式內定義的變數,在函式內使用 全域性變數:在函式外定義的變數,在程式任何地方都可以使用 1、全域性變數與區域性變數同名 這時函式內部只調用區域性變數,如果要呼叫全域性變數需要在函式內加一句“global 同名變數”

Python學習十二

Python基礎知識(11):高階特性 一、分片(切片)   通過索引來獲取一定範圍內的元素 #字串 s="Alice" s[0:4:2] 結果: 'Ai' #列表 l=[1,2,3,4,5,6] l[0:2] 結果: [1, 2] #元組 t=(1,2,3,"a","b","c"

Python學習十七

Python基礎知識(16):面向物件程式設計(Ⅰ) 類和例項 類是抽象的模板 例項是根據類創建出來的一個個具體的物件,每個物件都擁有相同的方法,但各自的資料可能不同。 類可以在建立例項的時候,把一些我們認為必須繫結的屬性強制填寫進去 方法就是與例項繫結的函式,和普通函式不同,方法可以直接訪問例項的

Python學習十八

expand red function encode tabs reduce repl nbsp 試圖 Python基礎知識(17):面向對象編程(Ⅱ) 獲取對象信息 在不知道對象信息的情況下,我們想要去獲取對象信息,可以使用以下方法 1、type (1)判斷對象類型 &

Python學習二十

mil 循環 函數 type() 高級編程 裝飾器 pri 綁定 沒有 Python基礎知識(19):面向對象高級編程(Ⅱ) 定制類 形如“__xx__”的變量或函數在Python中是有特殊用途的 1、__str__ 讓打印出來的結果更好看 __str__:面向用戶;__r

Python學習三十三

Python基礎知識(32):網路程式設計(Ⅰ) 網路通訊是兩臺計算機上的兩個程序之間的通訊,而網路程式設計就是如何在程式中實現兩臺計算機的通訊 P協議負責把資料從一臺計算機通過網路傳送到另一臺計算機 TCP協議則是建立在IP協議之上的。TCP協議負責在兩臺計算機之間建立可靠連線,保證資料包按順序到達

我的Unity開始—— 自訴

現在的境地:辭職一年、考研失敗、專業技能忘得差不多、身上沒有資金、面臨重新找工作的問題,嗯,沒有女朋友!!! 現在的想法:去上海、找同學、租房子、找工作、不找女朋友!!! 將來的方向:遊戲是大方向,一部分是因為我同學是遊戲策劃,可以一起幹點事情;一部分是不想玩Java了(不知道為什麼);

一個菜鳥的資料結構學習

棧的基本操作如下: 相關結構體: typedef int status; typedef struct { SElemType *base; //在棧建立之前和銷燬之後,base的值為NULL SElemType *top; //棧

linux 學習啟程

初次接觸linux真的是一頭無霧水,也不知道該何處下手,還好我比較幸運,遇到的同事很不錯,教我很多東西,你的人生遇到什麼樣的人真好很重要,真的很感謝他們。     我現在做的是嵌入式的前端,也就是GUI。     接下來我要端正我的學習態度,對自己有正確的定位,明白自己缺少

【itext學習路】-------第一建立一個簡單的pdf文件

iText是著名的開放原始碼的站點sourceforge一個專案,是用於生成PDF文件的一個java類庫。通過iText不僅可以生成PDF或rtf的文件,而且可以將XML、Html檔案轉化為PDF檔案 本教程中,首先要說明的是,itext技術在網上很少能有一個相對全面文

Android探索第十 推薦幾款非常好用的Bug除錯工具

首推 騰訊Bugly - 一種愉悅的開發方式是一款非常方便幫組開發者實時的檢測App的異常及應用統計,還有更加強大的應用更新及熱修復,讓你的App 6飛起 官網地址:https://bugly.qq