https://www.jianshu.com/p/91e9fee635c1
SurfaceView
-
SurfaceView可以直接在子線程中更新ui,顯示畫面流暢。
-
因爲SurfaceView提供雙緩衝機制。通過兩個線程交替在兩塊內存緩衝區繪製畫面。
-
直接繪製不通過點擊(直接在activity的oncreate方法中調用要創建監聽器,只有surfaceview創建後才能創建畫布,不能在surfaceview沒準備好就直接創建)
-
SurfaceView在繪製前要先鎖定畫布(獲取畫布),繪製完成後對畫布解鎖,把畫布的內容顯示到屏幕上
-
SurfaceHolder保持了surfaceView的對象,所以它管理着生命週期
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);// 1.查找控件 SurfaceView sv = (SurfaceView) findViewById(R.id.sv); // 2.獲得控制器 holder = sv.getHolder();
}
public void draw(View v) {
for (int i = 0; i < 100; i++) { // 繪製一個半徑變大圓 // 3.鎖定畫布 Canvas lockCanvas = holder.lockCanvas(); //清除上一幀內容 lockCanvas.drawColor(Color.BLACK); Paint paint = new Paint(); paint.setColor(Color.RED); // 利用畫布對象繪製 圓心x,y座標 半徑 畫筆對象 lockCanvas.drawCircle(120, 120, 5 + i, paint); // 5.解鎖並提交 holder.unlockCanvasAndPost(lockCanvas); }
}
import android.view.SurfaceHolder.Callback; 注意導包
// 1.查找控件
SurfaceView sv = (SurfaceView) findViewById(R.id.sv);
// 2.獲得控制器
holder = sv.getHolder();
//設置監聽器,當surface創建時,再繪製
holder.addCallback(new Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
System.out.println("當界面不可見時,surfaceDestroyed被調用了");
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
System.out.println("當界面可見時,surfaceCreated被調用了");
myDraw();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
System.out.println("當Surface尺寸或格式時變化,surfaceChanged被調用了");
}
});
-
draw是一個耗時不確定的方法,每次繪製耗費時間不同可能會顯示卡頓,一直draw對性能也會有影響,所以最好有延時操作
/**
-
繪製的主線程
*/
@Override
public void run() {
while (isThreadFlag) {
long start = System.currentTimeMillis();
try {
synchronized (CartSurfaceView.class) {
mCanvas = mSurfaceHolder.lockCanvas(); //} } catch (Exception e) { e.printStackTrace(); } finally { if (mCanvas != null) { mSurfaceHolder.unlockCanvasAndPost(mCanvas);//結束鎖定畫圖,並提交改變。 } } long end = System.currentTimeMillis(); // 讓線程休息100毫秒 if (end - start < 30) { try { Thread.sleep(30 - (end - start)); } catch (InterruptedException e) { e.printStackTrace(); } }
}
}
SurfaceView小遊戲之俄羅斯方塊(kotlin)
SurfaceView小遊戲之打飛機(kotlin)
遙感賽車
-