SurfaceView,onDraw和postInvalidate()出错了

时间:2012-03-24 21:48:21

标签: java android surfaceview ondraw

App表现得很奇怪。我有一个类扩展了SurfaceView并实现了SurfaceHolder.Callback 我尝试了3个代码选项,只有一个像我需要的那样工作(但我怀疑它是一个正确的解决方案)而其他有不同的行为。
所以,我的问题是为什么和什么是错的,如果“正确“解决方案是错误的,为什么它的工作......左右

适合所有人:

  1. 我尝试了setWillNotDraw(boolean flag) flag(true / false)
  2. 在清单集android:changeConfiguration="orientation"
  3. 在主布局设置背景中,通过xml资源定义平铺图片。
  4. 现在“正确”实施: 我有一个调用postInvalidate();的线程,在lockCanvas和unlockCanvas之间有延迟和调用:
    我的onDraw()和draw(Canvas c,int deg)在所有变体中都相同:

    @Override
    public void onDraw(Canvas c) {
        draw(c,lastHeading);
        super.onDraw(c);
    }
    
    public synchronized void draw(Canvas c,int degrees) {
        Paint p=new Paint();
        p.setAntiAlias(true);
        c.save();
    
        rotateLayer(degrees,layer1, cLayers.getDrawable(0),false);
        rotateLayer(lastSideAngle, layer2, sLayers.getDrawable(1),true);
        rotateLayer(lastFrontAngle, layer2, fLayers.getDrawable(1),true);
    
        c.drawBitmap(layer1,0, 0, p);
        c.drawBitmap(layer2,0, 0, p);
        c.drawBitmap(layer3, 0,0, p);   
        c.restore();
    }
    

    问题代码变体A(和“右”):

    @Override
    public void run() {
        Canvas c=null;
        try
        {
            c=holder.lockCanvas(null);
            synchronized (holder) {
            postInvalidate();
        }
        finally
        {
            if(c!=null)
            holder.unlockCanvasAndPost(c);
        }
    }
    

    为什么它的工作没有问题,但没有lock / unloc的相同代码没有工作corectly?

    下一个实现应用程序工作不错,直到手机不改变方向。在改变方向时,需要花时间重绘表面,但在下一个方向更改时,它会快速变化。但在两个变种中我调用postInvalidate()并且我不明白Canvas如何锁定/解锁postInvalidate()?

    @Override
    public void run() {
        postInvalidate();
    }
    

    在这个版本中,我在屏幕上看到一个永远不会变形的冻结图像:

    @Override
    public void run() {
        Canvas c=null;
        try
        {
            c=holder.lockCanvas(null);
            synchronized (holder) {
            draw(c,deg);
            //OR
            //onDraw(c)
        }
        finally
        {
            if(c!=null)
            holder.unlockCanvasAndPost(c);
        }
    }
    

    当app绘制所有位图但背景覆盖其全部时,还有一个变体。 那么我做错了什么,我需要做什么?

1 个答案:

答案 0 :(得分:0)

下面:

@Override
public void run() {
Canvas c=null;
   try
   {
       c=holder.lockCanvas(null);
       synchronized (holder) {
       draw(c,deg);
       //OR
       //onDraw(c)
   }
   finally
   {
       if(c!=null)
       holder.unlockCanvasAndPost(c);
   } 
}

您需要设置一个循环,因为否则您只调用一次onDraw()方法。 这将创建一个连续的重绘:

while(true) {
   try
   {
       c=holder.lockCanvas(null);
       synchronized (holder) {
       draw(c,deg);
       //OR
       //onDraw(c)
   }
   finally
   {
       if(c!=null)
       holder.unlockCanvasAndPost(c);
   } 
}

Source