1

In my onCreateOptionsMenu() I have basically the following:

public boolean onCreateOptionsMenu(Menu menu) {

        menu.add(Menu.NONE, MENU_ITEM_INSERT, Menu.NONE, R.string.item_menu_insert).setShortcut('3',
                'a').setIcon(android.R.drawable.ic_menu_add);

        PackageManager pm = getPackageManager();
        if(pm.hasSystemFeature(PackageManager.FEATURE_CAMERA) && pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_AUTOFOCUS)){
            menu.add(Menu.NONE, MENU_ITEM_SCAN_ADD, Menu.NONE, ((Collectionista.DEBUG)?"DEBUG Scan and add item":getString(R.string.item_menu_scan_add))).setShortcut('4',
                    'a').setIcon(android.R.drawable.ic_menu_add);
        }
        ...
}

And in onPrepareOptionsMenu among others the following:

final boolean scanAvailable = ScanIntent.isInstalled(this);
final MusicCDItemScanAddTask task = new MusicCDItemScanAddTask(this);          
menu.findItem(MENU_ITEM_SCAN_ADD).setEnabled(scanAvailable && (tasks == null || !existsTask(task)));

As you see, two options items have the same drawable set (android.R.drawable.ic_menu_add). Now, if in onPrepareOptionsMenu the second menu item gets disabled, its label and icon become gray, but also the icon of the first menu item becomes gray, while the label of that first menu item stays black and it remains clickable. What is causing this crosstalk between the two icons/drawables? Shouldn't the system handle things like mutate() in this case?

I've included a screenshot:

top menu item icon should not be gray

pjv
  • 10,658
  • 6
  • 43
  • 60

3 Answers3

3

http://www.curious-creature.org/2009/05/02/drawable-mutations/

The above article by Romain Guy explains this very situation and provides a work around.

Emile
  • 11,451
  • 5
  • 50
  • 63
  • Yes Emile, I know. But there you use the drawable in your code and have to do the mutate(). In this case, I don't touch it in code and count on the system to do the mutate() part (in the setEnabled() call). Unless I don't understand something. – pjv Jan 02 '11 at 16:15
  • The article explains as to why the system doesn't do the mutate. I.e. for efficiency. This means, i think, that what your experiencing is expected behaviour and you will have to either duplicate assets as Arhimed suggested or add code to mutate the icons your self. Androids letting you down in "..count on the system to do the mutate() part..." it simply isn't going to do that. – Emile Jan 02 '11 at 17:53
  • I still find it hard to believe. The webpage speaks of buttons too. However, when I press one button and it becomes orange, I don't see the similar button next to it also becoming orange. The system takes care of this. And the system should have taken care of this when calling MenuItem.setEnabled(). Calling ((Drawable) star).setAlpha() is a whole other kind of thing, as you really have the drawable in your hands and you call a pretty basic method on it. If my rough estimate that 20% of menu items drawables are shared isn't off, then why else have a setIcon(int) function? – pjv Jan 03 '11 at 19:45
  • I find quite a lot of android hard to believe, for example the complete lack of a horizontal list/gridview. Still there it is. By all accounts some components manage mutation automatically and others don't. I'm guessing depending on who wrote the component. You asked why, and the article explains that its because the bitmap is shared. As to where this holds true and doesn't i'm guessing you'll have to find out by trial and error. – Emile Jan 03 '11 at 19:55
  • So I first tried ".setIcon(android.R.drawable.ic_menu_add).getIcon().mutate();", which didn't work. Then I tried ".setIcon(getResources().getDrawable(android.R.drawable.ic_menu_add).mutate());" which ofcourse did. This is what I mean by saying the setIcon(int) would be useless. Emile, I'll grant you the answer for now, but I still find it hard to believe this is the intended way of working. – pjv Jan 03 '11 at 20:43
1

Yes, this looks odd. I can not explain why this is as it is, however I can propose a workaround - instead of using internal drawable resourse, you could put the same image in your app drawable resourse dir AND you could duplicate the add image, so you have 2 images - add_for_menu_item_1.png and add_for_menu_item_2.png named differently, but having the same visual representation. I am sure this would do the trick.

Vit Khudenko
  • 28,288
  • 10
  • 63
  • 91
  • 1
    I had the same thought. Its a shame you have to do that though. Perhaps as mentioned in the original post, you could manually mange the mutate() so as to avoid duplicating assets. Not sure how you'd do that though. – Emile Jan 02 '11 at 14:30
  • `MenuItem` has `getIcon()` that returns a `Drawable`. So it is possible to call mutate on the `Drawable`. I think this can solve the issue. – Vit Khudenko Jan 02 '11 at 14:42
  • I agree that this would likely work as a workaround. Thanks Arhimed. Any guesses to the cause? – pjv Jan 02 '11 at 16:17
  • @pjv: article provided by Emile explains the cause and point to the solution. Jut repeating the above my comment: `MenuItem` has getIcon() that returns a `Drawable`. So it is possible to call `mutate()` on the `Drawable`. – Vit Khudenko Jan 02 '11 at 18:51
0

Could it be that both menu items are sharing the same alphaChar which is causing the second menuItem to be disabled?

csaunders
  • 1,712
  • 1
  • 15
  • 20
  • Yes I do! I apparently assigned 'a' as a shortcut to both, and also shared the numerical shortcut with another. But I'm not seeing it working yet. I think this maybe it though. Thanks. I'm gonna have a better look and see if I can find any other overlaps. – pjv Jan 02 '11 at 16:34
  • Sorry, well spotted, but had nothing to do with it? – pjv Jan 03 '11 at 20:43