2011-10-02 7 views
7

に変更していませんではなく、肖像画に:起動時にアクションバー容量/オーバーフローが私が向きが自分自身を変える扱うアクションバーを使用して、アプリを持っている姿勢の変化

<?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 (はい、以下に示すように、私は、常に表示するようにして、彼らが収まるようにすべての項目を強制することもできますが、それは小さなタブレットに壊すかもしれない)

エミュレータが向きを変える、アクションバーの容量は変更されていないようです:私は風景の中に開始

ポートレート、: narrow ActionBar with all items in (これはOK、しかし、矛盾している)

ラン私が肖像画で始まったときの舞踏会: wide ActionBar with overflow これは私がこれを解決したい理由です。

私はinvalidateOptionsMenu()にこの呼び出しを追加したが、それは助けにはならない:

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

は(実際に私は、下位互換性のための反射によってそれを呼び出すが、デバッガはそれが本当にと呼ばれ、遭遇しないと言われます戻り値の前にonCreateOptionsMenu()(これはメニューを再膨張させます)を呼び出して終了します。後者の中で、getResources()。getConfiguration()の方向が既に変更されていることがわかります。これは本当に困惑しています。オプションメニューが再作成されている場合は、方向が変更されたときに、ActionBar自体が幅をキャッシュする必要がありますか?

アクティビティを破壊/作成せずにアクションバーを再作成する方法はありますか?(私の場合、後者は少し高価です)

編集:ここには、問題を示すminimal sample projectがあります。

編集2:私は、画面幅をチェックして、プログラムでいつもとは決して適切とのshowAsActionフラグを調整することを考えていたが、それは、各項目の幅を知っている(または推測)が必要です。 ActionBar's public APIはその点で私を助けません。

+0

あなたが問題を実証する完全なサンプルプロジェクトを作成して投稿することができますか?また、ハードウェアでこれを試しましたか?エミュレータ固有の問題である可能性があります。 – CommonsWare

+0

@CommonsWare [OK]を、サンプルプロジェクトの最後に私の編集を参照してください。私は現在、タブレットのハードウェアは持っていませんが、水曜日のタブレットについてはAndroid Developer Labのイベントに行く予定なので、おそらくそこで試してみることができます。 –

+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は、あまりにも新しいフィールドを使用して修正する必要があります。:-)

私は確かに(プラットフォームへの修正を待っている以外の)より良い答えに興味があります。

5

私はこの問題に遭遇し、100%動作するハックを思いつきました。

invalidateOptionsMenu()を2回呼び出すことを手伝った。以下のコードを見てください:

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. 
    } 
}