Android學習之旅(第一篇) SurfaceView的原理以及使用場景
為什麼要使用SurfaceView來實現動畫?
因為View的繪圖存在以下缺陷:
- View缺乏雙緩衝機制
- 當程式需要更新View上的影象時,程式必須重繪View上顯示的整張圖片
- 新執行緒無法直接更新View元件
SurfaceView的繪圖機制
- 一般會與SurfaceView結合使用
- 呼叫SurfaceView的getHolder()方法即可獲得SurfaceView關聯的SurfaceHolder
SurfaceHolder提供瞭如下方法來獲取Canvas物件
- Canvas lockCanvas():鎖定整個SurfaceView物件,獲取該Surface上的Canvas
- Canvas lockCanvas(Rect dirty):鎖定SurfaceView上Rect劃分的區域,獲取該Surface上的Canvas
- 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