上篇中提到了SurfaceView绘制触摸轨迹时出现的闪烁问题,这里就说明下产生这种困扰的根源——双缓存机制。

Android中的SurfaceView在更新视图时,为了提高更新效率,加强用户体验,采用了双缓存机制。

Android的官方说明有:

Note: On each pass you retrieve the Canvas from the SurfaceHolder, the previous state of the Canvas will be retained. In order to properly animate your graphics, you must re-paint the entire surface. For example, you can clear the previous state of the Canvas by filling in a color with drawColor() or setting a background image with drawBitmap(). Otherwise, you will see traces of the drawings you previously performed.

在运用时可以理解为:SurfaceView在更新视图时用到了两张Canvas,一张frontCanvas和一张backCanvas,每次实际显示的是frontCanvas,backCanvas存储的是上一次更改前的视图,当使用lockCanvas()获取画布时,得到的实际上是backCanvas而不是正在显示的frontCanvas,之后你在获取到的backCanvas上绘制新视图,再unlockCanvasAndPost(canvas)此视图,那么上传的这张canvas将替换原来的frontCanvas作为新的frontCanvas,原来的frontCanvas将切换到后台作为backCanvas。例如,如果你已经先后两次绘制了视图A和B,那么你再调用lockCanvas()获取视图,获得的将是A而不是正在显示的B,之后你讲重绘的C视图上传,那么C将取代B作为新的frontCanvas显示在SurfaceView上,原来的B则转换为backCanvas。

如下面的一段代码:

package com.tobacco.touchdraw;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;

public class TestView extends SurfaceView implements Callback{
private SurfaceHolder sfh;
private Canvas canvas;
private Paint paint;

public TestView(Context context) {
super(context);
sfh=this.getHolder();
sfh.addCallback(this);
paint=new Paint();
paint.setColor(Color.RED);
paint.setAntiAlias(true);
paint.setStrokeWidth(2);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeCap(Paint.Cap.ROUND);
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub

}

@Override
public void surfaceCreated(SurfaceHolder holder) {
for(int i=0;i<10;i++){
canvas=sfh.lockCanvas();
if(canvas!=null){
canvas.drawText(""+i,10,20*i,paint);
}
sfh.unlockCanvasAndPost(canvas);
}

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub

}

}
最终在屏幕上显示的,不会是0到9的10个数字,而是1,3,5,7,9五个奇数数字,原因是最后绘制的是带有这些奇数的那张缓冲画布,而所有的偶数数字将绘制到另一张缓冲画布上。


更多相关文章

  1. Android之使用AchartEngineActivity引擎绘制柱状图、曲线图
  2. ANDROID L——RecyclerView,CardView导入和使用
  3. Android(安卓)Cavans 基础应用
  4. Android(安卓)ViewPager初探:让页面滑动起来
  5. 【android之锚定视图】
  6. android 开发-Toast控件的实现
  7. cocos2dx 遮罩层 android 手机上 失败
  8. Mono for Android(安卓)实现高效的导航
  9. Android(安卓)Gallery3d源码学习总结(二)——绘制流程drawThumbnai

随机推荐

  1. 关于基本代码的10篇文章推荐
  2. 关于缩写词的详细介绍
  3. xml基础如何使用?总结xml基础实例用法
  4. 有关Xml.Serialization的文章推荐6篇
  5. 关于Spy的详细介绍
  6. 有关循环过程的文章推荐5篇
  7. 关于应用名称的文章推荐
  8. 用户列表的10篇内容推荐
  9. 关于OFBiz的详细介绍
  10. 有关UTF-16的问题及解决方法