Android - Как изменить цвет фона в меню параметров? - Qaru

Android - Как изменить цвет фона в меню параметров? - Qaru

Это явно проблема, с которой сталкиваются многие программисты и которой Google еще не предоставил удовлетворительное, поддерживаемое решение.

Есть много скрещенных намерений и недоразумений, плавающих вокруг сообщений по этой теме, поэтому, пожалуйста, прочитайте весь этот ответ, прежде чем отвечать.

Ниже я включаю более "утонченную" и хорошо прокомментированную версию взлома из других ответов на этой странице, также включающую идеи из этих очень близких вопросов:

Изменить цвет фона в меню Android

Как изменить цвет фона в меню параметров?

Android: настроить меню приложения (например, цвет фона)

http://www.macadamian.com/blog/post/android_-_theming_the_unthemable/

Android MenuItem Toggle Button

Возможно ли сделать фон меню меню Android непрозрачным?

http://www.codeproject.com/KB/android/AndroidMenusMyWay.aspx

Установка фонового фона меню

Я тестировал этот хак на 2.1 (симулятор), 2.2 (2 реальных устройства) и 2.3 (2 реальных устройства). У меня нет никаких 3.X-планшетов для тестирования, но я буду публиковать любые необходимые изменения здесь, когда/если я это сделаю. Учитывая, что 3.X-планшеты используют Action Bars вместо меню Options, как описано здесь:

http://developer.android.com/guide/topics/ui/menus.html#options-menu

этот хак почти наверняка ничего не сделает (никакого вреда и нечего) на планшетах 3.X.

ЗАЯВЛЕНИЕ О ПРОБЛЕМЕ (прочитайте это перед триггерным ответом с отрицательным комментарием):

Меню "Опции" имеет совершенно разные стили на разных устройствах. Чистый черный с белым текстом на некоторых, чистый белый с черным текстом на некоторых. Я и многие другие разработчики хотят контролировать цвет фона в ячейках меню "Параметры" , а также цвет текста меню "Параметры" .

Некоторым разработчикам приложений нужно установить цвет фона ячейки (не цвет текста), и они могут сделать это более чистым способом, используя стиль android: panelFullBackground, описанный в другом ответе. Однако в настоящее время нет способа контролировать цвет текста меню "Параметры" со стилями, и поэтому этот метод можно использовать только для изменения фона на другой цвет, который не заставит текст "исчезать".

Мы хотели бы сделать это с документированным, надежным решением, но его просто нет в Android-версии = 2.3. Поэтому мы должны использовать решение, которое работает в текущих версиях и предназначено для минимизации вероятности сбоя/взлома в будущих версиях. Нам нужно решение, которое изящно не возвращается к поведению по умолчанию, если оно должно потерпеть неудачу.

Существует много законных причин, по которым вам может понадобиться контролировать внешний вид меню "Параметры" (как правило, чтобы соответствовать визуальному стилю для остальной части приложения), поэтому я не буду останавливаться на этом.

Об этом сообщается об ошибке Google Android: добавьте свою поддержку, сняв эту ошибку с ошибкой (обратите внимание, что Google отговаривает "меня тоже": достаточно просто звезды):

http://code.google.com/p/android/issues/detail?id=4441

РЕЗЮМЕ РЕШЕНИЙ, КОТОРЫЕ ДОЛЖНЫ БЫТЬ:

Несколько плакатов предложили взломать с помощью LayoutInflater.Factory. Предлагаемый взлом работал для Android <= 2.2 и не удался для Android 2.3, потому что хак сделал недокументированное предположение: его можно было вызвать непосредственно из LayoutInflater.getView(), не находясь внутри вызова LayoutInflater.inflate() в том же экземпляре LayoutInflater, Новый код в Android 2.3 нарушил это предположение и привел к исключению NullPointerException.

Мой слегка утонченный хак ниже не полагается на это предположение.

Кроме того, хаки также полагаются на использование внутреннего недокументированного имени класса "com.android.internal.view.menu.IconMenuItemView" в виде строки (а не как типа Java). Я не вижу никакого способа избежать этого и все еще выполнить заявленную цель. Тем не менее, можно сделать взлом осторожным способом, который отпадет, если "com.android.internal.view.menu.IconMenuItemView" не появится в текущей системе.

Опять же, поймите, что это взломать и ни в коем случае не утверждаю, что это будет работать на всех платформах. Но мы, разработчики, не живем в фантастическом академическом мире, где все должно быть по книге: у нас есть проблема, и мы должны решить ее как можно лучше. Например, маловероятно, что "com.android.internal.view.menu.IconMenuItemView" будет существовать на таблетках 3.X, поскольку они используют Action Bars вместо меню "Параметры" .

Наконец, некоторые разработчики решили эту проблему, полностью подавив меню "Настройки Android" и написав свой собственный класс меню (см. некоторые из приведенных выше ссылок). Я не пробовал это, но если у вас есть время написать собственный просмотр и выяснить, как заменить Android-представление (я уверен, что черт в деталях здесь), то это может быть приятное решение, которое не требует каких-либо недокументированные хаки.

HACK:

Вот код.

Чтобы использовать этот код, вызовите addOptionsMenuHackerInflaterFactory() ONCE из вашей активности onCreate() или вашей активности onCreateOptionsMenu(). Он устанавливает по умолчанию factory, который повлияет на последующее создание любого меню параметров. Это не влияет на уже созданные меню параметров (предыдущие хаки использовали имя функции setMenuBackground(), что очень вводит в заблуждение, так как функция не устанавливает никаких свойств меню до того, как она вернется).

@SuppressWarnings("rawtypes") static Class IconMenuItemView_class = null; @SuppressWarnings("rawtypes") static Constructor IconMenuItemView_constructor = null; // standard signature of constructor expected by inflater of all View classes @SuppressWarnings("rawtypes") private static final Class[] standard_inflater_constructor_signature = new Class[] { Context.class, AttributeSet.class }; protected void addOptionsMenuHackerInflaterFactory() { final LayoutInflater infl = getLayoutInflater(); infl.setFactory(new Factory() { public View onCreateView(final String name, final Context context, final AttributeSet attrs) { if (!name.equalsIgnoreCase("com.android.internal.view.menu.IconMenuItemView")) return null; // use normal inflater View view = null; // "com.android.internal.view.menu.IconMenuItemView" // - is the name of an internal Java class // - that exists in Android <= 3.2 and possibly beyond // - that may or may not exist in other Android revs // - is the class whose instance we want to modify to set background etc. // - is the class we want to instantiate with the standard constructor: // IconMenuItemView(context, attrs) // - this is what the LayoutInflater does if we return null // - unfortunately we cannot just call: // infl.createView(name, null, attrs); // here because on Android 3.2 (and possibly later): // 1. createView() can only be called inside inflate(), // because inflate() sets the context parameter ultimately // passed to the IconMenuItemView constructor first arg, // storing it in a LayoutInflater instance variable. // 2. we are inside inflate(), // 3. BUT from a different instance of LayoutInflater (not infl) // 4. there is no way to get access to the actual instance being used // - so we must do what createView() would have done for us // if (IconMenuItemView_class == null) { try { IconMenuItemView_class = getClassLoader().loadClass(name); } catch (ClassNotFoundException e) { // this OS does not have IconMenuItemView - fail gracefully return null; // hack failed: use normal inflater } } if (IconMenuItemView_class == null) return null; // hack failed: use normal inflater if (IconMenuItemView_constructor == null) { try { IconMenuItemView_constructor = IconMenuItemView_class.getConstructor(standard_inflater_constructor_signature); } catch (SecurityException e) { return null; // hack failed: use normal inflater } catch (NoSuchMethodException e) { return null; // hack failed: use normal inflater } } if (IconMenuItemView_constructor == null) return null; // hack failed: use normal inflater try { Object[] args = new Object[] { context, attrs }; view = (View)(IconMenuItemView_constructor.newInstance(args)); } catch (IllegalArgumentException e) { return null; // hack failed: use normal inflater } catch (InstantiationException e) { return null; // hack failed: use normal inflater } catch (IllegalAccessException e) { return null; // hack failed: use normal inflater } catch (InvocationTargetException e) { return null; // hack failed: use normal inflater } if (null == view) // in theory handled above, but be safe... return null; // hack failed: use normal inflater // apply our own View settings after we get back to runloop // - android will overwrite almost any setting we make now final View v = view; new Handler().post(new Runnable() { public void run() { v.setBackgroundColor(Color.BLACK); try { // in Android <= 3.2, IconMenuItemView implemented with TextView // guard against possible future change in implementation TextView tv = (TextView)v; tv.setTextColor(Color.WHITE); } catch (ClassCastException e) { // hack failed: do not set TextView attributes } } }); return view; } }); }

Спасибо за чтение и наслаждение!

Android - Как изменить цвет фона в меню параметров? - Qaru
Как изменить внешний вид интерфейса на Android - Android для всех
Android - Как изменить цвет фона в меню параметров? - Qaru
Простой способ сменить фон фото или любого изображения
Android - Как изменить цвет фона в меню параметров? - Qaru
Скачать Поменять Фон На Фото APK 5.0 для Андроид. - APKA ndroid
Android - Как изменить цвет фона в меню параметров? - Qaru
Android - Как заменить белый фон? - Stack Overflow на русском
Android - Как изменить цвет фона в меню параметров? - Qaru
Приложение Product Camera создает белый фон вокруг
Android - Как изменить цвет фона в меню параметров? - Qaru
Приложения в Google Play Background Eraser
Android - Как изменить цвет фона в меню параметров? - Qaru
Android - Как изменить цвет фона в меню параметров? - Qaru
Android - Как изменить цвет фона в меню параметров? - Qaru
Android - Как изменить цвет фона в меню параметров? - Qaru
Android - Как изменить цвет фона в меню параметров? - Qaru
Android - Как изменить цвет фона в меню параметров? - Qaru
Android - Как изменить цвет фона в меню параметров? - Qaru
Android - Как изменить цвет фона в меню параметров? - Qaru
Android - Как изменить цвет фона в меню параметров? - Qaru