版权声明: https://blog.csdn.net/weixin_37165769/article/details/82190869
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(); } }
}
}