Як змінити колір тла меню параметрів?


96

Я намагаюся змінити колір за замовчуванням для меню параметрів, який є білим: я хочу чорний фон для кожного пункту меню параметрів.

Я спробував кілька знімків, таких як android: itemBackground = "# 000000" для елемента item в елементі меню, але це не спрацювало.

Як я можу це зробити?



Кращий спосіб тут stackoverflow.com/questions/3519277 / ...
user3156040

Відповіді:


65

Провівши значну кількість часу, випробувавши всі параметри, єдиним способом, яким я зміг отримати програму за допомогою AppCompat v7 для зміни фону переповнення меню, був використання атрибута itemBackground:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    ...
    <item name="android:itemBackground">@color/overflow_background</item>
    ...
</style>

Перевірено з API 4.2 на 5.0.


2
Це повинна бути прийнята відповідь, проста і проста.
Алекс Ардавін,

3
Але це усуває ефект пульсації: / Все одно повернути його назад?
Девід Веласкес,

Я хочу змінити фон цілого вікна, а не окремий фон елемента, наприклад, він додасть межі до кожного елемента, якщо ви встановите такий фон (з межами) ...
user25

1
А як щодо кольору тексту меню?
doctorram

51

Очевидно, що це проблема, яку має багато програмістів і для якої Google ще не запропонував задовільного рішення, що підтримується.

Багато перехрещених намірів та непорозумінь плаває навколо дописів на цю тему, тому, будь ласка, прочитайте всю цю відповідь перед тим, як відповісти.

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

Змінити колір фону меню Android

Як змінити колір тла меню параметрів?

Android: налаштуйте меню програми (наприклад, колір тла)

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

Кнопка перемикання меню в меню Android

Чи можна зробити фон меню параметрів Android непрозорим?

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

Встановлення непрозорого фону меню

Я протестував цей хак на 2.1 (симулятор), 2.2 (2 реальних пристрої) та 2.3 (2 реальних пристрої). У мене ще немає планшетів 3.X для тестування, але тут, коли / якщо я, буду розміщувати тут необхідні зміни. Враховуючи, що в планшетах 3.X використовуються панелі дій замість меню параметрів, як пояснюється тут:

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, оскільки вони використовують панелі дій замість меню параметрів.

Нарешті, деякі розробники вирішили цю проблему, повністю придушивши меню параметрів Android та написавши власний клас меню (див. Деякі посилання вище). Я не пробував цього, але якщо у вас є час написати власний подання та зрозуміти, як замінити вигляд Android (я впевнений, що диявол у деталях тут), це може бути гарним рішенням, яке не вимагає недокументовані хаки.

Злам:

Ось код.

Щоб скористатися цим кодом, викличте addOptionsMenuHackerInflaterFactory () ОДИН раз із вашої активності onCreate () або вашої діяльності onCreateOptionsMenu (). Він встановлює завод за замовчуванням, який впливатиме на подальше створення будь-якого меню параметрів. Це не впливає на вже створені меню параметрів (попередні хаки використовували ім'я функції 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's 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;
        }
    });
}

Дякуємо за читання та насолоджуйтесь!


15
Єдине, що я отримую надійно, намагаючись використати це (і подібне рішення), це `java.lang.IllegalStateException: На цьому LayoutInflater вже встановлена ​​фабрика
Бостон,

Працює для мене! Так здорово, що нарешті є рішення! Випробувано на пряниках, стільниках та ICS
Чад Шульц,

Перевірено в Samsung Galaxy Nexus (4.1.1) і працює! Хороші речі, Луї!
Феліпе Кальдас,

2
Працює на Galaxy Nexus 7 (4.1.1), однак колір тексту змінюється під час кожного наступного виклику в меню після першого приховування.
Will Kru

1
Я також отримую IllegalStateException. Схоже, хак несумісний із ActionBarSherlock, яким я користуюся.
Тревіс,

20

Атрибут стилю для фону меню - android:panelFullBackground.

Незважаючи на те, що сказано в документації, це повинен бути ресурс (наприклад, @android:color/blackабо @drawable/my_drawable), він вийде з ладу, якщо ви безпосередньо використовуєте значення кольору.

Це також позбавить меж елементів, які мені не вдалося змінити або видалити за допомогою рішення primalpop.

Що стосується кольору тексту, я не знайшов жодного способу встановити його за допомогою стилів у 2.2, і я впевнений, що спробував усе (саме так я виявив атрибут фону меню). Для цього вам потрібно буде використовувати розчин primalpop.


3
Де мені потрібно встановити це значення? Я не міг змусити його працювати на Android 2.2. або 2.3
Януш

1
@Janusz In Styles.xml. Це, мабуть, допоможе: developer.android.com/guide/topics/resources/…
Pilot_51

2
Не працює, чудово, якби ви могли вказати, куди це має йти, пробували скрізь, окрім створення іншого стилю для атрибутів моїх пунктів меню .....
Джон

14

Для Android 2.3 це можна зробити за допомогою дуже важкого злому:

Основною причиною проблем з Android 2.3 є те, що в LayoutInflater mConstructorArgs [0] = mContext встановлюється лише під час запуску викликів до

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3.3_r1/android/view/LayoutInflater.java/#352

protected void setMenuBackground(){

    getLayoutInflater().setFactory( new Factory() {

        @Override
        public View onCreateView (final String name, final Context context, final AttributeSet attrs ) {

            if ( name.equalsIgnoreCase( "com.android.internal.view.menu.IconMenuItemView" ) ) {

                try { // Ask our inflater to create the view
                    final LayoutInflater f = getLayoutInflater();
                    final View[] view = new View[1]:
                    try {
                        view[0] = f.createView( name, null, attrs );
                    } catch (InflateException e) {
                        hackAndroid23(name, attrs, f, view);
                    }
                    // Kind of apply our own background
                    new Handler().post( new Runnable() {
                        public void run () {
                            view.setBackgroundResource( R.drawable.gray_gradient_background);
                        }
                    } );
                    return view;
                }
                catch ( InflateException e ) {
                }
                catch ( ClassNotFoundException e ) {
                }
            }
            return null;
        }
    });
}

static void hackAndroid23(final String name,
    final android.util.AttributeSet attrs, final LayoutInflater f,
    final TextView[] view) {
    // mConstructorArgs[0] is only non-null during a running call to inflate()
    // so we make a call to inflate() and inside that call our dully XmlPullParser get's called
    // and inside that it will work to call "f.createView( name, null, attrs );"!
    try {
        f.inflate(new XmlPullParser() {
            @Override
            public int next() throws XmlPullParserException, IOException {
                try {
                    view[0] = (TextView) f.createView( name, null, attrs );
                } catch (InflateException e) {
                } catch (ClassNotFoundException e) {
                }
                throw new XmlPullParserException("exit");
            }   
        }, null, false);
    } catch (InflateException e1) {
        // "exit" ignored
    }
}

Я протестував його для роботи на Android 2.3 і для роботи з попередніми версіями. Якщо щось пізніше зламається в пізніших версіях Android, ви просто побачите стиль меню за замовчуванням


Цей код працює лише до версії 2.1. Цей код, здається, кращий: stackoverflow.com/questions/2944244/…
Феліпе Кальдас

Привіт, я використав вашу функцію, але отримав таку помилку: Помилка роздування класу com.android.internal.view.menu.IconMenuItemView, а потім ще одне виняток Помилка роздування класу <невідомо> ... що тепер мені робити ... ? будь ласка, допоможи мені.
Rushabh Patel

13

Щойно натрапив на цю проблему також у додатку, який повинен був бути сумісним з Gingerbread і при цьому зберігати якомога більше стилів із пристроїв із підтримкою Holo.

Я знайшов відносно чисте рішення, яке для мене спрацювало нормально.

У темі я використовую 9-патч для малювання фону, щоб отримати власний колір фону:

<style name="Theme.Styled" parent="Theme.Sherlock">
   ...
   <item name="android:panelFullBackground">@drawable/menu_hardkey_panel</item>
</style>

Я відмовився від спроб стилізувати колір тексту і просто використав Spannable, щоб встановити колір тексту для мого елемента в коді:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
   MenuInflater inflater = getSupportMenuInflater();
   inflater.inflate(R.menu.actions_main, menu);

   if (android.os.Build.VERSION.SDK_INT < 
        android.os.Build.VERSION_CODES.HONEYCOMB) {

        SpannableStringBuilder text = new SpannableStringBuilder();
        text.append(getString(R.string.action_text));
        text.setSpan(new ForegroundColorSpan(Color.WHITE), 
                0, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        MenuItem item1 = menu.findItem(R.id.action_item1);
        item1.setTitle(text);
   }

   return true;
}

чудово працює для мого випуску із використанням теми ActionBarSherlock Light на пристрої Gingerbread! Завдяки цьому я можу легко змінити фон меню параметрів на світло-сірий, а колір тексту на чорний (піктограми вже чорні, як на панелі дій! Дякую!
florianbaethge

12

Ось як я вирішив свою. Я щойно вказав колір тла та колір тексту у стилях. тобто res> values> files.xml файл.

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:itemBackground">#ffffff</item>
    <item name="android:textColor">#000000</item>
</style>

1
textcolor мінявся б скрізь
user3156040

він просто змінює колір фону елементів, а макет опцій меню має верхню та нижню відступ, це не допомагає
FarshidABZ

10

Зазначимо одне, що ви, хлопці, занадто ускладнюєте проблему, як і багато інших публікацій! Все, що вам потрібно зробити, - це створити селектори, які можна малювати, з будь-яким фоном, який вам потрібен, і встановити для них фактичні елементи. Я просто витрачаю дві години на випробування ваших рішень (усі запропоновані на цій сторінці), і жодне з них не спрацювало. Не кажучи вже про те, що є маса помилок, які суттєво уповільнюють вашу продуктивність у тих блоках try / catch, які у вас є.

У будь-якому разі тут є файл xml меню:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/m1"
          android:icon="@drawable/item1_selector"
          />
    <item android:id="@+id/m2"
          android:icon="@drawable/item2_selector"
          />
</menu>

Тепер у вашому item1_selector:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/item_highlighted" />
    <item android:state_selected="true" android:drawable="@drawable/item_highlighted" />
    <item android:state_focused="true" android:drawable="@drawable/item_nonhighlighted" />
    <item android:drawable="@drawable/item_nonhighlighted" />
</selector>

Наступного разу, коли ви вирішите поїхати до супермаркету через Канаду, спробуйте google maps!


Я цілком погоджуюся. Навіщо заново винаходити Android, коли він =) вже існує?
Фредрік

Чудово працює. Створіть список шарів, який можна малювати за допомогою вашого значка та потрібного фону. Єдина проблема полягає в тому, що я не знаю, чи можу я змінити колір тексту. Тому працює не кожен колір фону
Януш

52
Гарний, елегантний і абсолютно не вирішує проблему.
Aea

1
Якщо я не помиляюся, це просто змінює фон піктограми, а не сам пункт меню, який залишається білим.
Jrom

3
Це не питання питання. Це зовсім інша думка.
Костадін

4
 <style name="AppThemeLight" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:itemBackground">#000000</item>
</style>

це для мене прекрасно працює


як змінити колір заголовка
parvez rafi

3
    /* 
     *The Options Menu (the one that pops up on pressing the menu button on the emulator) 
     * can be customized to change the background of the menu 
     *@primalpop  
   */ 

    package com.pop.menu;

    import android.app.Activity;
    import android.content.Context;
    import android.os.Bundle;
    import android.os.Handler;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.InflateException;
    import android.view.LayoutInflater;
    import android.view.Menu;
    import android.view.MenuInflater;
    import android.view.View;
    import android.view.LayoutInflater.Factory;

    public class Options_Menu extends Activity {

        private static final String TAG = "DEBUG";

        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);

        }

        /* Invoked when the menu button is pressed */

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // TODO Auto-generated method stub
            super.onCreateOptionsMenu(menu);
            MenuInflater inflater = new MenuInflater(getApplicationContext());
            inflater.inflate(R.menu.options_menu, menu);
            setMenuBackground();
            return true;
        }

        /*IconMenuItemView is the class that creates and controls the options menu 
         * which is derived from basic View class. So We can use a LayoutInflater 
         * object to create a view and apply the background.
         */
        protected void setMenuBackground(){

            Log.d(TAG, "Enterting setMenuBackGround");
            getLayoutInflater().setFactory( new Factory() {

                @Override
                public View onCreateView ( String name, Context context, AttributeSet attrs ) {

                    if ( name.equalsIgnoreCase( "com.android.internal.view.menu.IconMenuItemView" ) ) {

                        try { // Ask our inflater to create the view
                            LayoutInflater f = getLayoutInflater();
                            final View view = f.createView( name, null, attrs );
                            /* 
                             * The background gets refreshed each time a new item is added the options menu. 
                             * So each time Android applies the default background we need to set our own 
                             * background. This is done using a thread giving the background change as runnable
                             * object
                             */
                            new Handler().post( new Runnable() {
                                public void run () {
                                    view.setBackgroundResource( R.drawable.background);
                                }
                            } );
                            return view;
                        }
                        catch ( InflateException e ) {}
                        catch ( ClassNotFoundException e ) {}
                    }
                    return null;
                }
            });
        }
    }

3
Будь ласка, не робіть цього: name.equalsIgnoreCase ("com.android.internal.view.menu.IconMenuItemView" Як видно з назви, використовується приватна інформація про реалізацію, і, отже, може зламатись на будь-якому оновлення платформи або пристрої.
hackbod

1
IconMenuItemView - це клас, який створює та контролює меню параметрів, яке походить від базового класу View. Цей клас походить із вихідного коду android і присутній принаймні з версії api 5. Я не бачу, щоб він зламався на будь-якому оновленні платформи чи пристрої.
Первинний Паппачан

1
Ви цього не бачите, бо не бачите майбутнього. Навіть якби був спосіб бути впевненим, це погана практика
HXCaine

Дякую, це дуже корисно. Однак це не працює в особливих випадках, таких як елементи, створені в onCreateOptionsMenu, але вимкнені в onPrepareOptionsMenu, але згодом знову ввімкнені.
HRJ

3

Дякую Маркусе! Він працює на 2.3 плавно, виправляючи деякі синтаксичні помилки, ось виправлений код

    protected void setMenuBackground() {
    getLayoutInflater().setFactory(new Factory() {

        @Override
        public View onCreateView(final String name, final Context context,
                final AttributeSet attrs) {

            if (name.equalsIgnoreCase("com.android.internal.view.menu.IconMenuItemView")) {

                try { // Ask our inflater to create the view
                    final LayoutInflater f = getLayoutInflater();
                    final View[] view = new View[1];
                    try {
                        view[0] = f.createView(name, null, attrs);
                    } catch (InflateException e) {
                        hackAndroid23(name, attrs, f, view);
                    }
                    // Kind of apply our own background
                    new Handler().post(new Runnable() {
                        public void run() {
                            view[0].setBackgroundColor(Color.WHITE);

                        }
                    });
                    return view[0];
                } catch (InflateException e) {
                } catch (ClassNotFoundException e) {

                }
            }
            return null;
        }
    });
}

static void hackAndroid23(final String name,
        final android.util.AttributeSet attrs, final LayoutInflater f,
        final View[] view) {
    // mConstructorArgs[0] is only non-null during a running call to
    // inflate()
    // so we make a call to inflate() and inside that call our dully
    // XmlPullParser get's called
    // and inside that it will work to call
    // "f.createView( name, null, attrs );"!
    try {
        f.inflate(new XmlPullParser() {
            @Override
            public int next() throws XmlPullParserException, IOException {
                try {
                    view[0] = (TextView) f.createView(name, null, attrs);
                } catch (InflateException e) {
                } catch (ClassNotFoundException e) {
                }
                throw new XmlPullParserException("exit");
            }
        }, null, false);
    } catch (InflateException e1) {
        // "exit" ignored
    }
}

1
Все, що я отримую за це: java.lang.IllegalStateException: На цьому LayoutInflater вже встановлено завод
Бостон,

щоб змусити його працювати з ActionBarSherlock і рамок сумісності і уникнути IllegalStateException побачити цей трюк stackoverflow.com/questions/13415284 / ...
avianey

3
protected void setMenuBackground() {
    getLayoutInflater().setFactory(new Factory() {
        @Override
        public View onCreateView (String name, Context context, AttributeSet attrs) {
            if (name.equalsIgnoreCase("com.android.internal.view.menu.IconMenuItemView")) {
                try {
                    // Ask our inflater to create the view
                    LayoutInflater f = getLayoutInflater();
                    final View view = f.createView(name, null, attrs);
                    // Kind of apply our own background
                    new Handler().post( new Runnable() {
                        public void run () {
                            view.setBackgroundResource(R.drawable.gray_gradient_background);
                        }
                    });
                    return view;
                }
                catch (InflateException e) {
                }
                catch (ClassNotFoundException e) {
                }
            }
            return null;
        }
    });
}

це XML-файл

gradient 
    android:startColor="#AFAFAF" 
    android:endColor="#000000"
    android:angle="270"
shape

1

Якщо ви хочете встановити довільний колір, це, здається, працює досить добре androidx. Випробувано на KitKat та Pie. Помістіть це у свій AppCompatActivity:

@Override public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
    if (name.equals("androidx.appcompat.view.menu.ListMenuItemView") &&
            parent.getParent() instanceof FrameLayout) {
            ((View) parent.getParent()).setBackgroundColor(yourFancyColor);
    }
    return super.onCreateView(parent, name, context, attrs);
}

Це встановлює колір android.widget.PopupWindow$PopupBackgroundView, який, як ви вже здогадалися, малює колір фону. Немає перетяжки, і ви також можете використовувати напівпрозорі кольори.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.