2012-02-07 318 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