2012-02-07 319 views
1

我有一个绘制在表面上的位图,每次旋转设备时都需要调整大小。由于软按钮,我用这个代码来获得当前尺寸(它似乎工作正常):Android surfaceChanged宽度/高度值不正确

public void getCanvasXY(){ 
    int currentapiVersion = android.os.Build.VERSION.SDK_INT; 
    if (currentapiVersion >= android.os.Build.VERSION_CODES.HONEYCOMB_MR2){ 
     // HoneyComb 3.2 and up 
     DisplayMetrics metrics = new DisplayMetrics(); 
     ((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(metrics); 
     Global.CanvasX = metrics.widthPixels; 
     Global.CanvasY = metrics.heightPixels; 
    } else{ 
     // before HoneyComb 
     Global.CanvasX = getWidth(); 
     Global.CanvasY = getHeight(); 
    } 
} 

我想重新计算的尺寸和创建我的位图()最好的地方是surfaceChanged。

@Override 
    public void surfaceChanged(SurfaceHolder holder1, int format, int width, int height) { 
       getCanvasXY(); 
       LoadBMP(); 
    } 

我看到这个叫不止一次,我也得到了CanvasX和设备的同时旋转CanvasY diferent值。最后一次调用工作正常,但我看到onDraw()如何绘制我的位图,精灵调整不好,最后确定。这是一个丑陋的影响。 如何解决这个问题? 谢谢

+0

请将“heigth”拼写为“height”,以便正确指出此问题。 – 2012-02-07 16:24:30

回答

0

这里我假设你的意思是SurfaceView,你使用的是后台线程绘制到曲面,而你正在使用SurfaceHolder.CallBack()。这不是一个完整的答案,但是,这个问题也困扰了我一段时间。在深夜排除故障之后,我设法制定了一种可能比您更优雅的解决方法。结果是在surfacechanged已经稳定到最后状态之前没有任何东西被绘制,所以用户不知道发生了什么。

在您的surfacechanged中,您会注意到您的高度或宽度未更改为正确的值,换言之,如果绘制的结果为MalFormed。你需要的是一个参考值,以您的高度和宽度应该是什么,你可以得到通过将下面的代码在你面前的setContentView()在您的主要活动:

WindowManager w = getWindowManager(); 
    Display d = w.getDefaultDisplay(); 
    int Meausredwidth = d.getWidth(); 
    int Measuredheight = d.getHeight(); 
从测量的高度和宽度

现在,算出你分配给SurfaceView的多少,并将这些值作为全局变量传递给你的SurfaceView。并确保您在主活动中的onconfigurationchanged()中调用上述代码,以便每次重新计算这些值。现在您SurfaceView应该以某种方式实施SurfaceHolder.Callback,改变你的surfacechanged看起来像这样:

@Override 
public void surfaceChanged(SurfaceHolder mholder, int format, int width, 
     int height) { 

    if (width != mWidth) { 
     MalFormed = true; 
     thread.setRunning(false); 
     count++; 

    } else if (width == mWidth) { 

     if (MalFormed) { 
      MalFormed = false; 

      Log.d("ROTATE", "ReDraw"); 

      thread = new DrawingThread(this, holder, mHandler); 
      thread.setRunning(true); 
      thread.start(); 

     } 

    } 

} 

哪里mWidth是所需的宽度。在这里,您可能需要根据具体问题更改if语句。 MalFormed是您的曲面视图中的全局布尔值。

现在需要记住的一点是,如果发生变化,SurfaceChanged()会在SurfaceCreated之前被调用,这意味着我们可以轻松修改任何试图与线程交互以适应上述变化的代码。

因此,在任何您尝试加入或开始绘制背景的线程中,您必须首先检查曲面是否为MalFormed。例如。

if (thread.getState() == State.TERMINATED){ 

      if(!MalFormed){ 
       holder.removeCallback(this); 
       holder = getHolder(); 
       holder.addCallback(this); 


       thread = new DrawingThread(this, holder,mHandler); 
       thread.setRunning(true); 

       thread.start(); 
      } 



     }else{ 
      if(!MalFormed){ 
       thread.setRunning(true); 

       try { 
        thread.join(); 
       } catch (InterruptedException e) { 

        e.printStackTrace(); 
       } 
      } 


     } 

希望我在某个地方看球。祝一切顺利。

+1

谢谢@digiphd。在开始时检查尺寸是我尝试做的,但我的800x480像素的平板电脑具有软按钮,当我从活动中获取尺寸时,尺寸将返回800x480。但问题是,真正有用的是760x480。我使用DisplayMetrics获得的值。 临时解决方案:等待一秒,直到旋转完成,确定正确的尺寸。足以确保这些值不会波动太多。对于我的应用程序就足够了,尽管我知道这不是最优雅的解决方案。 – user1194912 2012-08-02 00:20:36

+0

是的,这与我的解决方法类似。我只是等到尺寸匹配。希望这个线程也可以帮助其他人:) – digiphd 2012-08-03 00:58:21