Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MenuItem.setIcon() method doesn't work

I've tried already all possible solutions. Here's my code:

private Menu mMenu;

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.fragment_article_detail_menu, menu);
    mMenu = menu;
}

void changeStar(boolean added) {
    if (mMenu != null) {
        MenuItem item = mMenu.findItem(R.id.favourites_item);
        if (added) {
            Log.d(LOG_TAG, "Set full icon");
            item.setIcon(getResources().getDrawable(R.drawable.star_full));
        } else {
            Log.d(LOG_TAG, "Set empty icon");
            item.setIcon(getResources().getDrawable(R.drawable.star_empty));
        }
    }
}

Here is my menu xml file:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="ssidit.pp.ua.payspacereader.ArticleDetailActivity">
    <item
        android:id="@+id/refresh_item"
        android:title="@string/refresh"
        app:showAsAction="never"></item>

    <item
        android:id="@+id/favourites_item"
        android:icon="@drawable/star_empty"
        android:title="@string/add_to_favourite"
        app:showAsAction="ifRoom"></item>

    <item
        android:id="@+id/share_item"
        android:icon="@drawable/ic_share"
        android:title="@string/share"
        app:actionProviderClass="android.support.v7.widget.ShareActionProvider"
        app:showAsAction="ifRoom"></item>
</menu>

invalidateMenu() method doesn't help. When I call setIcon method, nothing changes on my android device.

Here is my code:

private boolean isFavourite;

 private void setValues(Cursor cursor) {

    Log.d(LOG_TAG, "Setting values");

    setData(titleTextView, CursorUtility.getTitle(cursor));
    setData(dateTextView, CursorUtility.getDateText(cursor));
    setData(timeTextView, CursorUtility.getTimeText(cursor));
    isFavourite = CursorUtility.isFavourite(cursor);
    getActivity().invalidateOptionsMenu();
}


@Override
public void onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);
    Log.d(LOG_TAG, "OnPrepareOptionsMenu");
    MenuItem item = menu.findItem(R.id.favourites_item);
    if (isFavourite) {
        Log.d(LOG_TAG, "Set full icon");
        item.setIcon(R.drawable.star_full);
    } else {
        Log.d(LOG_TAG, "Set empty icon");
        item.setIcon(R.drawable.star_empty);
    }
}

As you can see, everything is logged. So there can't be mistake if some method doesn't call. Also I checked item by getting title of it. It is right item. Just some kind of black magic.

like image 251
Serhii Tereshchenko Avatar asked Oct 20 '22 00:10

Serhii Tereshchenko


2 Answers

Try using invalidateOptionsMenu and move your changeStar logic to onPrepareOptionsMenu. From Android documentation:

public boolean onPrepareOptionsMenu (Menu menu)

Added in API level 1 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.

The default implementation updates the system menu items based on the activity's state. Deriving classes should always call through to the base class implementation.

like image 93
allo86 Avatar answered Oct 27 '22 10:10

allo86


Firstly: make a global variable of menu

Secondly: wherever in activity you want to change the icon just get that menu item by global variable menu using getItem() method instead of findItem.

Thirdly: set the icon to your menuItem returned by getItem() as follow menuItem.setIcon(res)

like image 29
Odai A. Ali Avatar answered Oct 27 '22 09:10

Odai A. Ali