2011-10-14 16 views
53

は、私は頻繁に/無効のメニュー項目を有効にしてonPrepareOptionsMenuからそれらが見えるようです。メニュー項目は、アクションバー上で最も使用を示すために私のAndroid 2.xのアプリケーションの一部にshowAsActionメニュー属性:は、どのように私はアクションバーをリフレッシュすることができますか?私のアプリの中で

今日、私はアンドロイドを追加し始めました。

アクションバーはすぐに有効化/無効化と可視性を反映していません。この変更が起こるのを見るには、右のメニュードロップダウンをクリックする必要があります。

[OK]を、私はメニューがonPrepareOptionsMenuを発射することを理解してください。 ActionBarをリフレッシュするには何が必要ですか?この変更はonOptionsItemSelectedから適用する必要があると思いますが、私は何を呼び出すべきか分かりません。ここで

メニューです:

<item 
    android:icon="@drawable/ic_menu_mapmode" 
    android:id="@+id/men_mapview" 
    android:showAsAction="ifRoom|withText" 
    android:title="@string/txt_mapview" /> 

<item 
    android:icon="@drawable/ic_menu_mapmode" 
    android:id="@+id/men_satelliteview" 
    android:showAsAction="ifRoom|withText" 
    android:title="@string/txt_satelliteview" /> 

はここonPrepareOptionsMenuです:私はinvalidateOptionsMenuを追加した場合、これはAndroidの3で動作します:

@Override 
public boolean onPrepareOptionsMenu(final Menu menu) { 
    MenuItem menuItemMapView = menu.findItem(R.id.men_mapview); 
    MenuItem menuItemSatelliteView = menu.findItem(R.id.men_satelliteview); 

    if (mapView.isSatellite()) { 
     menuItemMapView.setEnabled(true).setVisible(true); 
     menuItemmenuItemSatelliteView.setEnabled(false).setVisible(false); 
    } else { 
     menuItemMapView.setEnabled(false).setVisible(false); 
     menuItemmenuItemSatelliteView.setEnabled(true).setVisible(true); 
    } 

    return super.onPrepareOptionsMenu(menu); 
} 

ここonOptionsItemSelected

@Override 
public boolean onOptionsItemSelected(final MenuItem menuItem) { 
    switch (menuItem.getItemId()) { 
     case R.id.men_mapview: 
      mapView.setSatellite(false); 
      mapView.setStreetView(true); 
      mapView.invalidate(); 

      invalidateOptionsMenu(); // This works on Android 3.x devices only 
      return true; 
     case R.id.men_satelliteview: 
      mapView.setSatellite(true); 
      mapView.setStreetView(false); 
      mapView.invalidate(); 

      invalidateOptionsMenu(); // This works on Android 3.x devices only 
      return true; 
    } 

    return super.onOptionsItemSelected(menuItem); 
} 

EDITです。 xアプリがクラッシュするAndroid 2.xデバイスは、メソッドが見つからないために見つかりませんでした。それを正しく行うための推奨される方法は何ですか?

答えて

77

選択の私の方法は、ヘルパークラスを作成することです。

上記のコードで今すぐ
class VersionHelper 
{ 
    static void refreshActionBarMenu(Activity activity) 
    { 
     activity.invalidateOptionsMenu(); 
    } 
} 

、とinvalidateOptionsMenu();を置き換えます:たとえば、この方法のための

if (Build.VERSION.SDK_INT >= 11) 
{ 
    VersionHelper.refreshActionBarMenu(this); 
} 

クレジットはCommonsWareに行く(HoneycombHelperを検索し、彼の本をチェックアウト - 強くお勧めします)

+5

あなたの答えと単純にバージョンCHECを置く間differnece何kの最初の呼び出しを囲むif(Build.VERSION.SDK_INT> = 11){invalidateOptionsMenu(); }? versionHelperメソッド呼び出しでバージョンチェックを張っている可能性がありますか? – topwik

+9

@towpseヘルパークラスがそのまま構造化されている理由は、後方互換性がないためにクラッシュしないようにするためです。メソッド 'invalidateOptionsMenu()'は、API 11(ハニカム)以降にのみ存在します。あなたのアプリがAPI 11よりも低いもので動作するなら、クラッシュします。これを避けるには、問題のメソッドを別の** static **メソッド(例えば 'refreshActionBarMenu()')にラップし、** only ** API> 11で実行している場合はこの静的メソッドを呼び出します(バージョンチェック_before_あなたは静的メソッドを呼び出します)。これは 'VersionHelper'クラスが実際に使用されるまでロードされないために機能します。 –

+0

@Turbo ok cool、説明のためにありがとう、だから、elseのケースでは何をするだろうか?ユーザーが古いOSを使用している場合は、メニューを更新しないでください。 – topwik

10

メニューへの参照を保存して呼び出す:

this.menu.clear(); 
this.onCreateOptionsMenu(this.menu); 
+3

これは、API 11より前のデバイスのアクションバーにあるオプションメニュー項目の表示をプログラムで切り替える方法の正解です。 –

3

バ上の "Klaasvaak"の答えに記載されています。私はそのサブメヌスを使用しています。これは、私の作品:

// Declare and save the menu as global, so it can be called anywhere. 
Menu absTopSubMenus; 

public boolean onCreateOptionsMenu(Menu menu) { 

absTopSubMenus = menu; // Used for re-drawing this menu anywhere in the codes. 

// The remainder of your code below 
} 

を次に、これを再描画するだけ呼び出す:

// Redraw the top sub-menu 
absTopSubMenus.clear(); 
onCreateOptionsMenu(absTopSubMenus); 
3

を私はあなたがすでにそれを見ていることを確認していないが、あなたは広範囲に、そして計画をアクションバーを使用する場合より低いAPIをサポートするには(> 8)、actionBarSherlockライブラリを見てください。あなたはセクションに低下し、高いAPIののためのあなたのアクションバーコードを持っていないので、それはそれを作るだろう、そしてあなただけ実行することができます:ここで私たちに道を示すため@Klaasvaakする

runOnUiThread(new Runnable(){ 
    @Override 
    public void run(){ 
    supportInvalidateOptionsMenu(); 
    } 
}); 
+0

その最良のオプションです。 –

1

賞賛を。

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    mOptionsMenu = menu; 

    //... create and manage the menu normally 
} 
:あなたは経由して、私が達成メニュー(この場合はmOptionsMenu)への参照を保存する必要があり、

もちろん
private void invalidOptionsMenuHelper() { 
    if (Build.VERSION.SDK_INT >= 11) { 
     invalidateOptionsMenu(); 

    } else if (mOptionsMenu != null) { 
     mOptionsMenu.clear(); 
     onCreateOptionsMenu(mOptionsMenu); 
    } 
} 

:私は前と後のAPIレベル11の両方で動作し、次を使用します

14

使用

ActivityCompat.invalidateOptionsMenu(Activity activity) 

compatibility libraryから。

参照:受け入れ答えにhttps://stackoverflow.com/a/14748687/435855

+0

ジンジャーブレッドでは、このメソッドを呼び出した後でonCreateOptionsMenu()が呼び出されません。 – lemuel

+1

はい。 preHoneycombはスクリーンボタンをサポートしておらず、ハードウェアメニューボタンが期待されるためです。 onCreateOptionMenu()メソッドは、ユーザがメニューボタンを押すと呼び出されます。 invalidateOptionsMenuは、古いメニューのハードウェアボタンをサポートするアクションバー3.0+をリフレッシュすることに重点を置いています。 – Urizev

62

感謝。私はActionBarActivityを使用しています。このクラスでは、あなたが今、サポートライブラリでActionbarActivityからsupportInvalidateOptionsMenu()メソッドを使用することができます

supportInvalidateOptionsMenu(); 
+3

この人にクッキーを渡してください....メニューの表示をfalseに設定できない理由は、私がinvalidateOptionsMenu()を使用していることです。あなたの答えが見つかるまで。ありがとう、相棒。 – Cjames

+4

これが選択された回答である必要があります。 – Guy

+0

ツールバーのアクション(アイコン)はImageViewではなくTextViewで内部的に表現されているので、TextView内で複合ドロアブルを手作業で再描画し、押されたりアクティブ化されたときにそれらを再描画するTouchListenerを割り当てなければなりません。だから基本的に私はアイコンだけを着色しています。誰でも同様の状況ですか?メニューの無効化は私のためには機能しませんでした.. – milosmns

2

getActivity()invalidateOptionsMenuを()を使用して、サポートライブラリのV7をインポートする必要があるとしません。

が完了します。

0

はまた、あなたがあなたのメニューをリフレッシュしてきた直後に

myAppCompatActivity.setToolbarTitle("some dynamic title"); 

を呼び出していないことを確認してください。

私は、ドロアブルが表示される余地があっても表示されないという問題がありました。オリエンテーションを変更するとドロアブルが登場しました。要約すると

MainActivity:

public class MainActivity extends AppCompatActivity { 

    private boolean showMenu = true; 

    public void setShowMenu(boolean show) { 
     showMenu = show; 
     supportInvalidateOptionsMenu(); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.my_menu, menu); 
     menu.findItem(R.id.menu_share).setVisible(showMenu); 
     // menu.findItem(... 
     return true; 
    } 
} 

FragmentNoMenu:

public abstract class FragmentNoMenu extends Fragment { 

    protected MainActivity mainActivity; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setHasOptionsMenu(true); 
     mainActivity = (MainActivity) getActivity(); 
     if (mainActivity != null) { 
      mainActivity.setShowMenu(false); 
     } 
    } 

} 

FragmentWithMenu:

public abstract class FragmentWithMenu extends Fragment { 

    protected MainActivity mainActivity; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setHasOptionsMenu(true); 
     mainActivity = (MainActivity) getActivity(); 
     if (mainActivity != null) { 
      mainActivity.setShowMenu(true); 
     } 
    } 

} 
関連する問題