Android: изменение отображаемых состояний пунктов меню параметров, похоже, имеет побочные эффекты

В моем onCreateOptionsMenu() у меня есть в основном следующее:

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);
        }
        ...
}

А в onPrepareOptionsMenu среди прочего следующее:

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

Как видите, два элемента параметров имеют один и тот же набор рисунков (android.R.drawable.ic_menu_add). Теперь, если в onPrepareOptionsMenu второй элемент меню отключается, его метка и значок становятся серыми, но и значок первого элемента меню становится серым, а метка этого первого элемента меню остается черной и по нему можно щелкнуть. Что вызывает эти перекрестные помехи между двумя значками/рисунками? Разве в этом случае система не должна обрабатывать такие вещи, как mutate()?

Я включил скриншот:

Значок элемента верхнего меню не должен быть серым


person pjv    schedule 02.01.2011    source источник


Ответы (3)


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

Вышеупомянутая статья Ромена Гая объясняет именно эту ситуацию и предлагает обходной путь.

person Emile    schedule 02.01.2011
comment
Да, Эмиль, я знаю. Но там вы используете drawable в своем коде и должны выполнять mutate(). В этом случае я не трогаю его в коде и рассчитываю на то, что система выполнит часть mutate() (в вызове setEnabled()). Если я чего-то не понимаю. - person pjv; 02.01.2011
comment
В статье объясняется, почему система не выполняет мутацию. т.е. для эффективности. Это означает, я думаю, что то, что вы испытываете, является ожидаемым поведением, и вам придется либо дублировать активы, как предложил Архимед, либо добавить код для изменения значков самостоятельно. Андроиды подводят вас в .. рассчитывают на то, что система выполнит часть mutate () ... она просто не собирается этого делать. - person Emile; 02.01.2011
comment
Мне все еще трудно поверить. На веб-странице также говорится о кнопках. Однако, когда я нажимаю одну кнопку, и она становится оранжевой, я не вижу, чтобы похожая кнопка рядом с ней также становилась оранжевой. Система позаботится об этом. И система должна была позаботиться об этом при вызове MenuItem.setEnabled(). Вызов ((Drawable) star).setAlpha() — это совсем другое дело, поскольку у вас действительно есть рисуемый объект, и вы вызываете для него довольно простой метод. Если моя приблизительная оценка того, что 20% рисунков элементов меню являются общими, не ошибочна, то зачем еще нужна функция setIcon(int)? - person pjv; 03.01.2011
comment
Мне трудно поверить во многие элементы Android, например, в полное отсутствие горизонтального списка/сетки. Все еще есть. По общему мнению, некоторые компоненты управляют мутацией автоматически, а другие нет. Я предполагаю, что в зависимости от того, кто написал компонент. Вы спросили, почему, и в статье объясняется, что это потому, что растровое изображение является общим. Что касается того, где это верно, а где нет, я думаю, вам придется выяснить это методом проб и ошибок. - person Emile; 03.01.2011
comment
Итак, я сначала попробовал .setIcon(android.R.drawable.ic_menu_add).getIcon().mutate();, но это не сработало. Затем я попробовал .setIcon(getResources().getDrawable(android.R.drawable.ic_menu_add).mutate()); что конечно и произошло. Вот что я имею в виду, говоря, что setIcon(int) бесполезен. Эмиль, я дам вам ответ на данный момент, но мне все еще трудно поверить, что это предполагаемый способ работы. - person pjv; 03.01.2011

Да, это выглядит странно. Я не могу объяснить, почему это так, однако я могу предложить обходной путь - вместо использования внутреннего ресурса для рисования вы можете поместить одно и то же изображение в каталог ресурсов для рисования вашего приложения И вы можете дублировать изображение add, поэтому у вас есть 2 изображения - add_for_menu_item_1.png и add_for_menu_item_2.png названы по-разному, но имеют одинаковое визуальное представление. Я уверен, что это поможет.

person Vit Khudenko    schedule 02.01.2011
comment
У меня была такая же мысль. Хотя жаль, что вам приходится это делать. Возможно, как упоминалось в исходном посте, вы могли бы вручную управлять mutate(), чтобы избежать дублирования ресурсов. Хотя не уверен, как ты это сделаешь. - person Emile; 02.01.2011
comment
MenuItem имеет getIcon(), который возвращает Drawable. Таким образом, можно вызвать mutate для Drawable. Думаю, это может решить проблему. - person Vit Khudenko; 02.01.2011
comment
Я согласен, что это, вероятно, сработает как обходной путь. Спасибо Архимеду. Есть предположения о причине? - person pjv; 02.01.2011
comment
@pjv: статья, предоставленная Эмилем, объясняет причину и указывает на решение. Просто повторяю мой комментарий выше: MenuItem имеет getIcon(), который возвращает Drawable. Таким образом, можно позвонить mutate() на Drawable. - person Vit Khudenko; 02.01.2011

Может ли быть так, что оба элемента меню используют один и тот же alphaChar, что приводит к отключению второго элемента меню?

person csaunders    schedule 02.01.2011
comment
Да! Очевидно, я назначил «а» в качестве ярлыка для обоих, а также поделился числовым ярлыком с другим. Но я пока не вижу, чтобы это работало. Я думаю, что это может быть все же. Спасибо. Я посмотрю получше и посмотрю, смогу ли я найти какие-либо другие совпадения. - person pjv; 02.01.2011
comment
Извините, хорошо подмечено, но не имеет к этому никакого отношения? - person pjv; 03.01.2011