SurfaceView的入門(一)----初始surfaceView
轉載:https://blog.csdn.net/rong_wz/article/details/51956463
轉載:https://www.jianshu.com/p/acf574f08efc
轉載:https://blog.csdn.net/android_cmos/article/details/68955134
什麼是surface?
我們知道Activity是用了來顯示介面的,那麼Activity的介面是如何繪製出來的呢?這個肯定和Surface有關,但是博主是新手,具體關聯就不清楚,博主自己理解,Surface
什麼是surfaceView?
surfaceView本身繼承於view,符合view的所有特性,但是還不夠嚴謹,看下圖。
上圖是SurfaceView原始碼,可以知道SurfaceView的建立會新建一個視窗,而這個newMyWindow(this)
如何surfaceView?
首先SurfaceView也是一個View,它也有自己的生命週期。因為它需要另外一個執行緒來執行繪製操作,所以我們可以在它生命週期的初始化階 段開闢一個新執行緒,然後開始執行繪製,當生命週期的結束階段我們插入結束繪製執行緒的操作。這些是由其內部一個SurfaceHolder物件完成的。
SurfaceView它的繪製原理是繪製前先鎖定畫布(獲取畫布),然後等都繪製結束以後在對畫布進行解鎖 ,最後在把畫布內容顯示到螢幕上。
通常情況下,使用以下步驟來建立一個SurfaceView的模板:
(1)建立SurfaceView
建立自定義的SurfaceView繼承自SurfaceView,並實現兩個介面:SurfaceHolder.Callback和Runnable.程式碼如下
public class MySurfaceView extends SurfaceView implements Runnable,SurfaceHolder.Callback{
通過實現這兩個介面,就需要在自定義的SurfaceView中實現介面的方法,對於SurfaceHolder.Callback方法,需要實現如下方法,其實就是SurfaceView的生命週期:
@Override
public void surfaceCreated(SurfaceHolder holder) {
mIsDrawing = true;
new Thread(this).start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mIsDrawing = false;
}
對於Runnable介面,需要實現run()方法,
@Override
public void run() {
while (mIsDrawing){
try {
mCanvas = mHolder.lockCanvas();
// draw sth繪製過程
} catch (Exception e) {
} finally {
if (mCanvas != null)
mHolder.unlockCanvasAndPost(mCanvas);//保證每次都將繪圖的內容提交
}
}
}
(2)初始化SurfaceView
在自定義的MySurfaceView的構造方法中,需要對SurfaceView進行初始化,包括SurfaceHolder的初始化、畫筆的初始化等。在自定義的SurfaceView中,通常需要定義以下三個成員變數:
private SurfaceHolder mHolder;
private Canvas mCanvas;//繪圖的畫布
private boolean mIsDrawing;//控制繪畫執行緒的標誌位
SurfaceHolder,顧名思義,它裡面儲存了一個對Surface物件的引用,而我們執行繪製方法本質上就是操控Surface。SurfaceHolder因為儲存了對Surface的引用,所以使用它來處理Surface的生命週期。(說到底 SurfaceView的生命週期其實就是Surface的生命週期)例如使用 SurfaceHolder來處理生命週期的初始化。
初始化程式碼如下:
public MySurfaceView(Context context) {
super(context);
initView();
}
private void initView() {
mHolder = getHolder();//獲取SurfaceHolder物件
mHolder.addCallback(this);//註冊SurfaceHolder的回撥方法
setFocusable(true);
setFocusableInTouchMode(true);
this.setKeepScreenOn(true);//保持螢幕常亮
}
public MySurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
(2)SurfaceView總體使用
package com.slide.aier.myview;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
/**
* Created by aier on 2018/6/23.
*/
public class MySurfaceView extends SurfaceView implements Runnable,SurfaceHolder.Callback{
private SurfaceHolder mHolder;
private Canvas mCanvas;//繪圖的畫布
private boolean mIsDrawing;//控制繪畫執行緒的標誌位
public MySurfaceView(Context context) {
super(context);
initView();
}
private void initView() {
mHolder = getHolder();//獲取SurfaceHolder物件
mHolder.addCallback(this);//註冊SurfaceHolder的回撥方法
setFocusable(true);
setFocusableInTouchMode(true);
this.setKeepScreenOn(true);//保持螢幕常亮
}
public MySurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mIsDrawing = true;
new Thread(this).start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mIsDrawing = false;
}
@Override
public void run() {
while (mIsDrawing){
try {
mCanvas = mHolder.lockCanvas();
// draw sth繪製過程
} catch (Exception e) {
} finally {
if (mCanvas != null)
mHolder.unlockCanvasAndPost(mCanvas);//保證每次都將繪圖的內容提交
}
}
}
}