根据打开的片段更改操作栏中的选项菜单图标

时间:2013-10-04 14:50:42

标签: android android-fragments icons menuitem android-optionsmenu

我的选项菜单中有这个项目:

<item
    android:id="@+id/opt_mnu_action"
    android:icon="@android:drawable/ic_dialog_info"
    android:orderInCategory="1"
    android:showAsAction="ifRoom"
    android:title="New">
</item>

菜单本身在主FragmentActivity中创建。我想根据打开的Fragment以编程方式更改此项目的图标,显然,当用户点击此按钮时会有不同的操作。我尝试了几件事,但没有任何效果。我尝试的最后一件事就是我的Fragment的onCreateView方法中的代码:

MenuItem mi = (MenuItem) view.findViewById(R.id.opt_mnu_action);
mi.setIcon(R.drawable.ico_1);

但我的应用程序崩溃了。有没有办法做到这一点?

**更新**

以下是我现在要做的事情,所有这些都在我的主要主要FragmentActivity中: 首先,我的层次结构视图中有MenuItem action_button;。然后在我的onCreateOptionsMenu方法中实例化它:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.options_menu, menu);
    action_button = menu.findItem(R.id.opt_mnu_action);
    return super.onCreateOptionsMenu(menu);
}

然后我创建了这个功能,根据打开的标签更改图标:

public void change_action_button_icon(int tab_position)
{
    switch(tab_position)
    {
    case 0:
        action_button.setIcon(R.drawable.ico_1);
        break;
    case 1:
        action_button.setIcon(R.drawable.ico_2);
        break;
    case 2:
        action_button.setIcon(R.drawable.ico_3);
        break;
    }
    invalidateOptionsMenu();
}

我用onTabSelected方法调用它:

public void onTabSelected(ActionBar.Tab tab,
        FragmentTransaction fragmentTransaction) {
    mViewPager.setCurrentItem(tab.getPosition());
    setTab_position(tab.getPosition());
    change_action_button_icon(tab.getPosition());
}

但是一旦我启动我的应用程序 - 它崩溃了。我在此行收到NullPointerException错误:

action_button.setIcon(R.drawable.ico_1);

我猜 - 这是因为在action_button实例化之前请求了图标更改。但我不知道如何克服它......

3 个答案:

答案 0 :(得分:19)

使用此命令获取对菜单项的引用:

    menu.findItem(resourceId).setIcon(drawableId);

您必须将代码更改为onCreateOptionsMenu()中的图标。

请参阅下面的示例:

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

    getMenuInflater().inflate(R.menu.option_menu, menu);

    if (needToChangeMenuItem){

        menu.findItem(resourceId).setIcon(drawableId);
    }

    manageMenuIcon(menu);

    needToChangeMenuItem = false;


    return true;
}


    public void manageMenuIcon(Menu menu){
    if (bluetoothIconOn){
        menu.findItem(R.id.secure_connect_scan).setIcon(R.drawable.bluetoothon);
    } else
        menu.findItem(R.id.secure_connect_scan).setIcon(R.drawable.bluetoothoff);

    if (gpsIconOn)
        menu.findItem(R.id.gps).setIcon(R.drawable.gps);
    else
        menu.findItem(R.id.gps).setVisible(false);

    if (slipAndDropIconOn)
        menu.findItem(R.id.fall).setIcon(R.drawable.fall);
    else
        menu.findItem(R.id.fall).setVisible(false);

    if (fesConnectIconOn)
        menu.findItem(R.id.fesConnection).setIcon(R.drawable.fesconnect);
    else
        menu.findItem(R.id.fesConnection).setVisible(false);


}


    public void changeMenuItem(int resId, int draId){


    needToChangeMenuItem = true;
    resourceId = resId;
    drawableId = draId;

    invalidateOptionsMenu();        


}

答案 1 :(得分:0)

MenuItem mi = (MenuItem) view.findViewById(R.id.opt_mnu_action);
mi.setIcon(R.drawable.ico_1);

在你的片段onCreateOptionsMenu中,加载此菜单,并保留对菜单项的引用(它不是片段视图层次结构的一部分,因此您无法使用findViewById)。

当您准备好更新图标时,请使用mi.setIcon(R.drawable.ico_1); 并致电invalidateOptionsMenu()

更新:

return super.onCreateOptionsMenu(menu);

这实际上会返回false,因为基本实现不会这样做。取而代之的是跳过它,或者先调用super.onCreateOptionsMenu(menu);,然后再做你的东西,然后返回true。

答案 2 :(得分:0)

首先将actionOverFlowButtonStyle添加到主题

<style name="AppTheme" parent="AppBaseTheme">

    <item name="android:actionOverflowButtonStyle">@style/MyActionButtonOverflow</item>
</style>

定义动作按钮的新样​​式按钮

<style name="MyActionButtonOverflow" parent="android:style/Widget.Holo.Light.ActionButton.Overflow">
    <item name="android:src">@drawable/ic_menu</item>
</style>