web-dev-qa-db-ja.com

開いているフラグメントに応じてアクションバーのオプションメニューアイコンを変更する

私のオプションメニューにこのアイテムがあります:

<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のonCreateViewメソッドにあるこのコードです:

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

しかし、私のアプリはクラッシュしました。それを行う方法はありますか?

**​​ UPDATE **

ここで私が今やろうとしていることを、すべてメインのメイン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がインスタンス化されました。しかし、それを克服する方法がわかりません...

13
Igal

これを使用して、メニュー項目への参照を取得します。

    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();        


}
19
ksu
_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を返します。

0
f2prateek

まず、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>