动态更改ActionBar中的图标

61

我有一个Activity,它有一个ActionBar,但是我需要动态更改ActionBar上的图标。我有一个暂停和一个播放按钮,当用户点击时,我需要将播放按钮替换为暂停按钮。我搜索了一下,找到了解决方案:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    if(DEBUG) Log.i("onCreateOptionsMenu()", "onCreateOptionsMenu() -> LogicAnalizerView");
    //menu.add("").setIcon(R.drawable.pause).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.actionbarlogic, menu);
    menu.removeItem(R.id.pauseLogic);

    return true;
}

这样我就可以删除或添加暂停按钮,但仅发生在我启动Activity并绘制ActionBar时。如何强制重绘ActionBar?此方法还会重新绘制整个ActionBar。对吗?有没有办法只重绘我想要的按钮/图标?

谢谢 :)


9
这个链接实际上有一个“在运行时更改菜单项”的部分! - trumpetlicks
1
谢谢,它完美地工作了,看起来这是正确的做法 :) - Andres
6个回答

56

在进行膨胀操作之后,您需要保存 MenuItem 的引用。因此,可以使用以下类似代码:

public boolean onCreateOptionsMenu( Menu menu ) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate( R.menu.actionbarlogic, menu );
    playMenu = menu.findItem(R.id.playMenu);
    updatePlayStatus();
    return menu;
}

public void updatePlayStatus() {
    if( playService.isConnected() ) {
        playService.isPlaying() ? playMenu.setIcon(R.drawable.pause) : playMenu.setIcon(R.drawable.play);
    }
}

那么您可以随时引用playMenu。因此,当您的播放器完成播放并应返回到播放图标时,您可以将其修改为所需项。


2
谢谢,但我已经通过Android开发者的链接使其工作。 - Andres
@NeonWarge 这是他自己的代码,请忽略它,你只需要专注于 playMenu - chjarder
6
这不是最佳实践。Android开发者文章(链接在另一个问题中)和API清楚地展示了实现动态菜单按钮操作的最佳途径。 - Sipty

20

你可以隐藏你不想显示的按钮,而不是将它们移除。

例如:

private boolean isPlaying;
MenuItem mPlayMenuItem;
MenuItem mPauseMenuItem;

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu items for use in the action bar
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.actionbarlogic, menu);

    mPlayMenuItem = menu.findItem(R.id.action_play);
    mPauseMenuItem = menu.findItem(R.id.action_pause);

    return super.onCreateOptionsMenu(menu);

}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {
        case R.id.action_play:
            isPlaying = true;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                this.invalidateOptionsMenu();
            }
            return true;
        case R.id.action_pause:
            isPlaying = false;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                this.invalidateOptionsMenu();
            }
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}


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

    if (isPlaying) {
        mPlayMenuItem.setVisible(false); // hide play button
        mPauseMenuItem.setVisible(true); // show the pause button
    } else if (!isPlaying) {
        mPlayMenuItem.setVisible(true); // show play button
        mPauseMenuItem.setVisible(false); // hide the pause button
    }

    return true;
}

仅作一点说明,这个:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
     this.invalidateOptionsMenu();
}

需要更新操作栏。在3.0设备之后,操作栏不会自动更新。因此,您必须手动调用“OnPrepareOptionsMenu(Menu)”以使其通过调用“Activity.invalidateOptionsMenu()”刷新项。

希望这有所帮助!

参考:http://developer.android.com/reference/android/app/Activity.html#onPrepareOptionsMenu(android.view.Menu)

http://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#invalidateOptionsMenu(android.app.Activity)


11
private Menu mMenu;

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main_activity, menu);

    // Save the menu reference
    mMenu = menu;
    return super.onCreateOptionsMenu(menu);
}

// For example - Call when you need to change icon
private void setActionIcon(boolean showWithBadge)
{
    MenuItem item = mMenu.findItem(R.id.ITEM_ID);

    if(mMenu != null)
    {
        if(showWithBadge)
        {
            item.setIcon(R.drawable.IC_WITH_BADGE);           
        }
        else 
        {
            item.setIcon(R.drawable.IC_WITHOUT_BADGE);
        }
    }
}

3

如果您想从菜单中获取第一项,**

使用menu.getItem(0);

这段代码完美地工作:

 @Override
public boolean onCreateOptionsMenu(Menu menu) {

    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.my_menu, menu);
       MenuItem m =  menu.getItem(0);
       m.setIcon(R.drawable.your_icon_here);
    }


    return true;
}

2

使用invalidateOptionsMenu()方法。

private boolean isPlaying;

public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.actionbarlogic, menu);
    if (isPlaying) menu.removeItem(R.id.play_button);
    else menu.removeItem(R.id.pause_button);
    return true;
}

public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.play_button:
            // Do what the play button should do here
            isPlaying = true;
            break;

        case R.id.pause_button:
            // Do what the pause button should do here
            isPlaying = false;
            break;
    }
    invalidateOptionsMenu();
    return true;
}

2

在您的活动类中覆盖 onPrepareOptionsMenu 方法,然后您就可以添加/删除或显示/隐藏菜单项。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接