一、SurfaceView是View的孪生兄弟
View通过刷新来重绘视图,安卓系统通过发出VSYNC信号来进行屏幕重绘,刷新间隔是16ms。如果一次重绘耗时太长超过16ms会出现警告的log告诉你主线程可能做太多事情
SurfaceView的刷新是被动的,我们让他刷新的时候才执行刷新操作。并且SurfaceView使用了双缓冲而View没有
二、SurfaceView的使用
SurfaceView可以使用模板进行编写,这里做了一个模板如下所示
public abstract class SurfaceViewTemplate extends SurfaceView implements SurfaceHolder.Callback, Runnable { public SurfaceViewTemplate(Context context) { super(context); initView(context); } public SurfaceViewTemplate(Context context, AttributeSet attrs) { super(context, attrs); initView(context); } public SurfaceViewTemplate(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(context); } public SurfaceViewTemplate(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); initView(context); } protected SurfaceHolder mHolder; protected void initView(Context context) { mHolder = getHolder(); mHolder.addCallback(this); setFocusable(true); setKeepScreenOn(true); setFocusableInTouchMode(true); } boolean mIsDrawing; @Override public void surfaceCreated(@NonNull SurfaceHolder holder) { mIsDrawing = true; new Thread(this).start(); // 开线程出来进行绘制操作 } @Override public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(@NonNull SurfaceHolder holder) { mIsDrawing = false; } private final long DRAW_DURATION = 50; @Override public void run() { while (mIsDrawing) { long startTime = System.currentTimeMillis(); drawSurface(); long endTime = System.currentTimeMillis(); if (endTime - startTime < DRAW_DURATION) { // 让drawSurface每50毫秒刷一次,低于50毫秒则通过sleep把资源让出来 try { Thread.sleep(DRAW_DURATION - (endTime - startTime)); } catch (InterruptedException e) { e.printStackTrace(); } } } } private void drawSurface() { Canvas canvas = null; try { canvas = mHolder.lockCanvas(); // 获取画布,并在该画布上面进行绘制 if (canvas != null) { drawSurface(canvas); } } catch (Exception e) { } finally { if (canvas != null) { mHolder.unlockCanvasAndPost(canvas); // 将画布的内容进行提交 } } } /** * 让子类实现该方法来执行绘图操作 * */ protected abstract void drawSurface(Canvas canvas); }
三、使用二模板实现一个动态绘制正弦图的例子
private Path mPath; private Paint mPaint; @Override protected void initView(Context context) { // 继承父类的initView进行初始化 super.initView(context); mPath = new Path(); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.STROKE); mPaint.setColor(Color.BLACK); mPaint.setStrokeWidth(10); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStrokeCap(Paint.Cap.ROUND); } @Override public void surfaceCreated(@NonNull SurfaceHolder holder) { mPath.moveTo(0, 400); super.surfaceCreated(holder); } private int x = 0; private int y = 0; @Override protected void drawSurface(Canvas canvas) { // 继承父类的drawSurface进行绘制想要的图 canvas.drawColor(Color.WHITE); canvas.drawPath(mPath, mPaint); x += 1; y = (int) (100 * Math.sin(x * Math.PI / 180) + 400); mPath.lineTo(x, y); }
标签:canvas,mPaint,int,安卓,SurfaceView,void,context,public From: https://www.cnblogs.com/czwlinux/p/17026550.html