web-dev-qa-db-ja.com

AndroidのオプションメニューでMenuItemを変更するにはどうすればよいですか?

ActivityMenuItem "Start"のオプションメニューがあります。このMenuItemが選択されている場合、MenuItem "Stop"が含まれるようにメニューを変更します。そして最後に「停止」が選択されたら、「開始」に戻りたいと思います。

動作していないコードの一部を次に示します。 mymenu.xmlに「開始」と「停止」の両方がリストされています。メニューの作成時に「停止」を削除する必要があります。

public class MyActivity extends Activity {
    private boolean isStarted = false;

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        menu.removeItem(R.id.stop);
        inflater.inflate(R.menu.mymenu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.start:
            isStarted = true;
            return true;
        case R.id.stop:
            isStarted = false;
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        if(isStarted) {
            menu.removeItem(R.id.start);
            menu.add(R.id.stop);
        } else {
            menu.removeItem(R.id.stop);
            menu.add(R.id.start);
        }
        return true;
    }
}
42
Jonas

このタイプの操作では、通常、メニュー項目を変更せず、必要のないものだけを非表示にすることを選択します。

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);
    menu.findItem(R.id.start).setVisible(!isStarted);
    menu.findItem(R.id.stop).setVisible(isStarted);
    return true;
}
96
Flygenring

Flygenring答えは正しいが、menu.findItem()は遅延し、onPrepareOptionsMenu(Menu menu )悪いユーザーエクスペリエンスを生成します。メニューを作成するときにMenuItemオブジェクトを1回取得し、メニューが画面に表示されるたびにsetVisibleを呼び出すだけの方が良いでしょう:

    MenuItem mDynamicMenuItem;

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        // Get dynamic menu item
        mDynamicMenuItem = menu.findItem(R.id.menu_item);
        return true;
    }

    // Prepare the Screen's standard options menu to be displayed. This is called right 
    // before the menu is shown, every time it is shown. You can use this method to
    // efficiently enable/disable items or otherwise dynamically modify the contents.
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);
        // Here is just a good place to update item
        mDynamicMenuItem.setVisible(isVisible);
        return true;
    }
20
i.shadrin

変更を終えたら、おそらくsuper.onPrepareOptionsMenuを呼び出す必要があります。 docs から:

派生クラスは、常に基本クラスの実装を呼び出す必要があります。

6
Cheryl Simon

私は解決策を得た。基本的に、removeItem()を呼び出すときにMenuItemを削除するため、参照も削除されます。このコードを使用すると動作します。

private boolean isStarted = false;

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case 1:
        isStarted = true;
        return true;
    case 0:
        isStarted = false;
        return true;
    default:
        return super.onOptionsItemSelected(item);
    }
}

@Override
public boolean onPrepareOptionsMenu(Menu menu) {

    if(isStarted) {
        menu.removeItem(1);
        menu.add(0, 0, 0, "Stop");
    } else {
        menu.removeItem(0);
        menu.add(0, 1, 0, "Start");
    }

    return super.onPrepareOptionsMenu(menu);
}

MenuItemを再度作成する必要があります。それがfalseラベルの理由でもあります。実際には、コードを介してMenuInflaterを作成するときにMenuは必要ないため、メニューXMLファイルも必要ありません。

3

私のメニューの誤ったラベルの問題を解決したので、この投稿の情報に感謝します。私はそれをわずかに修正し、次のようにうまく機能する最終的なコードを持たなければなりませんでした。そのソリューションはわずかに異なりますが、主な変更は.setVisibleをTrueまたはFalseに変更することでした。i.shadrinsソリューションは私のニーズに最適でした。

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

    if(loggedIn) 
    {
        logIn.setVisible(false);
        logOut.setVisible(true);
    } 
    else 
    {
        logIn.setVisible(true);
        logOut.setVisible(false);
    }
    return true;
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    logIn = menu.findItem(R.id.loggedOut);
    logOut = menu.findItem(R.id.loggedIn);
    return true;
}
1
timv

Android 3.0以降では、invalidateOptionsMenu()を呼び出して、システムが呼び出すことを要求する必要がありますonPrepareOptionsMenu()その後、メソッド内のオプションメニューを変更できます。実行時にメニュー項目を変更できますセクションのAndroidドキュメントはこちら https://developer.Android.com/guide/topics/ui/menus#options-men その他詳細。

0
Dara