SurfaceView的onDraw()方法问题

View的onDraw函数是protected的。

protected 表明被它修饰的成员变量为保护类型,在同一个包里和 public 类型是一样的,也是能够访问到的。但是如果在不同包里的 protected 类型的成员变量就只能通过子类来访问,这个修饰符是区别于其他的修饰符的。

所以SurfaceView可以访问。而SurfaceView里并没有重写onDraw,所以View子类的子类可以重写onDraw,但不能访问,所以像你说的:即使写了onDraw函数,也不会自动调用,需要自己调用。

 

今天才做了一点SurfaceView的示例,例子很简单,就是画一些矩形,圆啊什么的。

这才知道,原来SurfaceView重写onDraw()方法是没有用的。SurfaceView中画图的关键对象Canvas对象必须要从一个SurfaceHolder对象获取:

Canvas canvas = holder.lockCanvas();

拿到canvas之后就可以进行绘画了。绘画完毕之后还要做的一件事就是提交绘画

holder.unlockCanvasAndPost();

从方法的命名可以看出,这个方法将原来锁定的(lockCanvas())的画板解除锁定,然后将画板的内容Post提交出去,相比应该是提交给SurfaceView,然后显示出来。

 

 

在继承SurfaceView的类中即使重写了onDraw()方法也是没有用的,因为SurfaceView虽然继承自View,但并没
重写onDraw(),其子类可以重写onDraw()但并不能自动调用。
解决办法:
首先SurfaceView的子类XXX要 implements SurfaceHolder.Callback,然后定义private SurfaceHolder sh = null;
在其构造函数中:
public XXX(Context context, AttributeSet attrs) {
     super(context, attrs);
     // TODO Auto-generated constructor stub
        sh = getHolder();
        sh.addCallback(this);
}
//自定义绘制函数
public void doDraw(){
    Paint p = new Paint(); // 笔触
    p.setAntiAlias(true); // 反锯齿
    p.setColor(Color.RED);
    p.setStyle(Style.STROKE);
    Canvas canvas = sh.lockCanvas();
    canvas.drawColor(Color.WHITE);//背景
    canvas.drawRect(10, 10, 100, 100, p);  
    sh.unlockCanvasAndPost(canvas); //提交绘制内容

 

}
在需要绘制的地方调用doDraw()即可。
//继承自view的onDraw方法
@Override
 protected void onDraw(Canvas canvas) {
  // TODO Auto-generated method stub
      super.onDraw(canvas);
      Paint p = new Paint(); // 笔触
      p.setAntiAlias(true); // 反锯齿
      p.setColor(Color.RED);
      p.setStyle(Style.STROKE);
      canvas = sh.lockCanvas();
      canvas.drawColor(Color.WHITE);//背景色
      canvas.drawRect(10, 10, 200, 200, p);  
      sh.unlockCanvasAndPost(canvas); //提交绘制内容
 }
在需要绘制的地方调用onDraw(null)即可。
注:重写SurfaceView的draw(),最终还是调用的onDraw(),但是调用draw(null)时会有异常。

 

posted @ 2013-03-26 09:55  Alex.Net  阅读(729)  评论(0编辑  收藏  举报