Androidでメニュー項目のテキストを動的に変更する方法


212

onOptionsItemSelected(MenuItem item)メソッドの外からメニュー項目のタイトルを変更しようとしています。

私はすでに次のことをしています。

public boolean onOptionsItemSelected(MenuItem item) {
  try {
    switch(item.getItemId()) {
      case R.id.bedSwitch:
        if(item.getTitle().equals("Set to 'In bed'")) {
          item.setTitle("Set to 'Out of bed'");
          inBed = false;
        } else {
          item.setTitle("Set to 'In bed'");
          inBed = true;
        }
        break;
    }
  } catch(Exception e) {
    Log.i("Sleep Recorder", e.toString());
  }
  return true;
}

ただし、このメソッドの外で特定のメニュー項目のタイトルを変更できるようにしたいと思います。


stackoverflow.com/a/32072318/1651286は受け入れられる答えである必要があります
Akhil Dad

回答:


127

JxDarkAngelが示唆したように、これをアクティビティのどこからでも呼び出すことができます。

invalidateOptionsMenu();

そしてオーバーライド:

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
  MenuItem item = menu.findItem(R.id.bedSwitch);
    if (item.getTitle().equals("Set to 'In bed'")) {
        item.setTitle("Set to 'Out of bed'");
        inBed = false;
    } else {
        item.setTitle("Set to 'In bed'");
        inBed = true;
    }
  return super.onPrepareOptionsMenu(menu);
}

はるかに良い選択です。https://stackoverflow.com/a/17496503/568197からの回答を使用しました


最良のソリューション。これは、ホイールを再発明するのではなく、androidメソッドをオーバーライドするためです。
Azlan Jamal

onPrepareOptionsMenu()たとえば、アクティビティを表示するときやメニューが表示されるたびに、Androidフレームワークによってかなり頻繁に呼び出されることに注意してください。したがって、メニューが頻繁に変更されない場合、これはあまり効率的ではありません。
Mr-IDE

1
invalidateOptionsMenu()もを呼び出すonCreateOptionsMenu()ため、更新ロジックをに配置できますonCreateOptionsMenu()
Mr-IDE、

これを編集して質問に関連する場合は、承認済みの回答としてマークします
Garbit

元の質問のコードを使用するように@Garbitが更新されました!
Todd DeLand

375

onCreateOptionsMenuで受け取ったMenuオブジェクトへの参照をアクティビティ内に保持し、それを使用して、必要に応じて変更が必要なMenuItemを取得することをお勧めします。たとえば、次のように何かを行うことができます。

public class YourActivity extends Activity {

  private Menu menu;
  private String inBedMenuTitle = "Set to 'In bed'";
  private String outOfBedMenuTitle = "Set to 'Out of bed'";
  private boolean inBed = false;

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);

    // Create your menu...

    this.menu = menu;
    return true;
  }

  private void updateMenuTitles() {
    MenuItem bedMenuItem = menu.findItem(R.id.bedSwitch);
    if (inBed) {
      bedMenuItem.setTitle(outOfBedMenuTitle);
    } else {
      bedMenuItem.setTitle(inBedMenuTitle);
    }
  }

}

または、onPrepareOptionsMenuをオーバーライドして、メニューが表示されるたびにメニュー項目を更新することもできます。


1
私は常にAndroidがこの種の問題に対してより洗練された解決策を持つことを期待しています。多くの場合、最も単純な答えが最も良いようです-ありがとう。
Steven Wolfe、

12

これを行うと、グローバルな「メニュー」オブジェクトを作成して、onCreateOptionMenuで割り当てることができます。

public class ExampleActivity extends AppCompatActivity
    Menu menu;

次にここに割り当てます

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu, menu);
    this.menu = menu;
    return true;
}

次に、割り当てられたMenuオブジェクトを使用して、必要なアイテムを取得します

menu.findItem(R.id.bedSwitch).setTitle("Your Text");

5

setOptionsTitle()メソッドを作成し、クラスにフィールドを設定します。といった:

String bedStatus = "Set to 'Out of Bed'";

...

public void setOptionsTitle(String status)
{
    bedStatus = status;

}

メニューが表示されたら、タイトルをステータスに変更します。

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);

        menu.add(bedStatus);


        // Return true so that the menu gets displayed.
        return true;
    }

アクティビティがレンダリングされた後に設定できるようにする必要があります。したがって、これらの2つの方法の内側ではない
ガービット2011

アクティビティがレンダリングされた後の任意の時点でsetOptionsTitleを呼び出します。「アクティビティがレンダリングされた後に設定できるようにする必要がある」という意味でsetContent(R.layout.id)を呼び出した後、私はあなたが何を望んでいるのか理解していません。オプションを変更する必要があるかもしれませんメニューが表示されます(これは、setOptionsTitle()で実行できます-どのメソッドからでも、いつでも、どこでも)。
ジャック

このアプローチは機能しますが、メニューを管理するMenuオブジェクトはタイトルがいつ変更されたかを知らないため、タイトルが変更されたときに必要になる可能性のあるタスク(レイアウトや改行など)を実行できないため、お勧めしません。 。
Charles Harley

3

オーバーライドonPrepareOptionsMenuを使用する方が良い

menu.Clear ();
   if (TabActual == TabSelec.Anuncio)
   {
       menu.Add(10, 11, 0, "Crear anuncio");
       menu.Add(10, 12, 1, "Modificar anuncio");
       menu.Add(10, 13, 2, "Eliminar anuncio");
       menu.Add(10, 14, 3, "Actualizar");
   }
   if (TabActual == TabSelec.Fotos)
   {
       menu.Add(20, 21, 0, "Subir foto");
       menu.Add(20, 22, 1, "Actualizar");
   }
   if (TabActual == TabSelec.Comentarios)
   {
       menu.Add(30, 31, 0, "Actualizar");
   }

ここに例


実際、意図したアプローチを使用してください。:)メニューへのローカル参照を保持する場合は、コンテキストリークを心配する必要があると思います。またはそうでないかもしれません。しかし、確かにこのアプローチではありません。
ウィリアムT.マラード2015年

3

このコードを使用して、下部のナビゲーションアイテムを原価計算します

BottomNavigationView navigation = this.findViewById(R.id.my_bottom_navigation);
Menu menu = navigation.getMenu();
menu.findItem(R.id.nav_wall_see).setTitle("Hello");

2

メニューフィールドを宣言します。

private Menu menu;

以下はonCreateOptionsMenu()メソッドです

public boolean onCreateOptionsMenu(Menu menu) {
this.menu = menu;
    try {
        getMenuInflater().inflate(R.menu.menu_main,menu);
    } catch (Exception e) {
        e.printStackTrace();
        Log.i(TAG, "onCreateOptionsMenu: error: "+e.getMessage());
    }
    return super.onCreateOptionsMenu(menu);
}

以下はあなたの名前設定アクティビティです。ボタンクリックまたは条件付きコードのいずれか

public void setMenuName(){
menu.findItem(R.id.menuItemId).setTitle(/*Set your desired menu title here*/);
}

これでうまくいきました。


0

ローカルメソッド内のメニューの内容を変更したいようですが、このメソッドは、イベントが発生するたびに、またはアクティビティUIスレッドでいつでも呼び出されます。

これがオーバーライドされ、このメソッドで使用されている場合は、onPrepareOptionsMenuのグローバル変数でMenuのインスタンスを取得しませんか。このメソッドは、ボタンのクリックなどのイベントが発生したとき、またはアクティビティのUIスレッド、ハンドラー、非同期タスクの実行後などに必ず呼び出されるようにしてください。

変更するこのメニュー項目のインデックスを事前に知っておく必要があります。メニューをクリアした後、メニューのXMLを膨らませ、アイテムの名前またはアイコンを更新する必要があります。


0

タイトルを静的に設定する必要がある人向け。これはAndroidManifest.xmlで行うことができます

<activity
    android:name=".ActivityName"
    android:label="Title Text" >
</activity>

オプションメニューのタイトルテキスト


3
質問は静的ではなく動的です。
EngineSense 2015年

まだグーグル検索で
思い付き

0

フラグメントのメニューアイコンを変更する必要がありました。この質問に対するチャールズの回答を少し変更しました。

    private Menu top_menu;

    //...
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

       setHasOptionsMenu(true);
       //...
       rootview = inflater.inflate(R.layout.first_content,null);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.fragment_menu, menu);
        this.top_menu = menu;
    }


    // my procedure
    private void updateIconMenu() {
         if(top_menu!= null) {
             MenuItem nav_undo = top_menu.findItem(R.id.action_undo);
             nav_undo.setIcon( R.drawable.back);
         }
    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.