2011-10-02 59 views
7

我必須使用動作條,我在那裏處理方向更改自己的應用程序:動作條容量/溢出不改變的方向變化

android:configChanges="keyboard|keyboardHidden|orientation|screenSize" 

...和菜單應該適合在動作條無溢出景觀,但沒有人像:

<?xml version="1.0" encoding="utf-8"?> 
<menu xmlns:android="http://schemas.android.com/apk/res/android"> 
<item android:title="@string/Game" android:id="@+id/game" android:icon="@android:drawable/ic_menu_manage"  android:showAsAction="ifRoom|withText"/> 
<item android:title="@string/Type" android:id="@+id/type" android:icon="@android:drawable/ic_menu_edit"  android:showAsAction="ifRoom|withText"/> 
<item android:title="@string/Other" android:id="@+id/other" android:icon="@android:drawable/ic_menu_gallery" android:showAsAction="ifRoom|withText"/> 
<item android:title="@string/Solve" android:id="@+id/solve" android:icon="@android:drawable/ic_menu_directions" android:showAsAction="ifRoom|withText"/> 
<item android:title="@string/Help" android:id="@+id/help" android:icon="@android:drawable/ic_menu_help"  android:showAsAction="ifRoom"/> 
</menu> 

在啓動時,該工作正常:

景觀: wide ActionBar with all items in

肖像: narrow ActionBar with overflow (是的,我可能會迫使所有的項目都始終顯示,他們會適應,如下圖所示,但可能會在一個較小的平板電腦打破)

當模擬器改變方向,ActionBar的能力似乎並沒有改變: narrow ActionBar with all items in (這是確定的,但不一致)

蘭:

人像,當我開始景觀dscape,當我開始肖像時: wide ActionBar with overflow 這看起來很傻,是我想解決這個問題的原因。

我加入這個電話轉給invalidateOptionsMenu(),但它並不能幫助:

@Override 
public void onConfigurationChanged(Configuration newConfig) 
{ 
    maybeMoveSomeViewsAround(newConfig); 
    super.onConfigurationChanged(newConfig); 
    invalidateOptionsMenu(); 
} 

(實際上我把它通過向後兼容反映,但調試器告訴我,這真的是所謂的和不會遇到()例外。)

invalidateOptionsMenu()實際上在返回之前最終調用onCreateOptionsMenu()(它重新膨脹菜單),並且我可以在後面看到getResources()。getConfiguration()。orientation已經改變。所以這真的令人費解。如果正在重新創建選項菜單,當方向改變時,它必須是ActionBar本身緩存的寬度?

有沒有辦法重新創建ActionBar而不破壞/創建活動?(因爲後者在我的情況下有點貴)

編輯:這是minimal sample project顯示的問題。

編輯2:我曾經想過檢查屏幕寬度並以編程方式調整showAsAction標誌總是和從不適當的,但這需要知道(或猜測)每個項目的寬度。 ActionBar's public API在這一點上沒有幫助我。

+0

您可以創建和發佈一個完整的示例項目演示問題?另外,你有沒有在硬件上嘗試過?這可能是一個模擬器特定的問題。 – CommonsWare

+0

@CommonsWare好的,請參閱我的編輯樣本項目的結尾。我目前沒有平板電腦硬件,但週三將參加關於平板電腦的Android開發者實驗室活動,所以我可以推測在那裏嘗試。 –

+1

我可以在運行Android 3.2的XOOM上重現問題。這感覺就像一個錯誤。我已經提出並提出了一個問題:http://code.google.com/p/android/issues/detail?id=20493 – CommonsWare

回答

2

我已經謹慎地解決了這個問題:當設備的寬度大於850dip時,強制顯示ActionBar中的所有項目,否則繼續讓平臺決定。

Here's the git commit編輯:follow-up commit使用太新的字段進行修復,oops。:-)

我絕對仍然對更好的答案感興趣(除了等待修復平臺)。

5

我遇到了這個問題,並提出了一個黑客工作100%。

我支持兩次調用invalidateOptionsMenu()。看看下面的代碼:

private boolean hackActionBarReset = false; 

@Override 
public void onConfigurationChanged(Configuration newConfig) { 
    super.onConfigurationChanged(newConfig); 

    //a hack to reset the items in the action bar. 
    hackActionBarReset = true; 
    invalidateOptionsMenu(); 
    hackActionBarReset = false; 
    invalidateOptionsMenu(); 

} 

而在你的onCreateOptionsMenu()設置此你的菜單項要顯示:

item.setShowAsAction(MenuItem.SHOW_AS_ACTION_WITH_TEXT | (hackActionBarReset ? MenuItem.SHOW_AS_ACTION_NEVER : MenuItem.SHOW_AS_ACTION_IF_ROOM)); 

不漂亮的解決方案,但它的工作原理。

1

我發現最簡單和最有效的解決方法是清除菜單,然後重建它。

例如:

Menu menu; 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    this.menu = menu; 
    // Setup code goes here... 
} 

@Override 
public void onOrientationChanged() { 
    if (menu != null) { 
     menu.close(); // Ensure the menu is closed before changing its contents. 
     menu.clear(); 
     onCreateOptionsMenu(menu); // Rebuild the menu. 
    } 
}