Seçenekler menüsünün arka plan rengi nasıl değiştirilir?


98

Beyaz olan seçenekler menüsünün varsayılan rengini değiştirmeye çalışıyorum: Seçenekler menüsündeki her öğe için siyah bir arka plan istiyorum.

Menü öğesi içindeki öğe öğesinde android: itemBackground = "# 000000" gibi bazı çekimleri denedim ama işe yaramadı.

Bunu nasıl başarabilirim?



Yanıtlar:


66

Tüm seçenekleri denemek için önemli miktarda zaman harcadıktan sonra, taşma menüsü arka planını değiştirmek için AppCompat v7 kullanarak bir uygulama edinebilmemin tek yolu itemBackground özelliğini kullanmaktı:

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

API 4.2'den 5.0'a kadar test edilmiştir.


2
Kabul edilen cevap bu olmalı, kolay ve basit.
Alex Ardavin

4
Ama bu dalgalanma etkisini ortadan kaldırır: / Neyse, geri koymak için?
David Velasquez

Ayrı öğe arka planını değil, tüm pencere arka planını değiştirmek istiyorum, örneğin, böyle bir arka planı ayarlarsanız (kenarlıklarla) her öğeye kenarlıklar ekleyecektir ...
kullanıcı25

1
Menü metni rengi ne olacak?
doctorram

51

Bu, pek çok programcının sahip olduğu ve Google'ın henüz tatmin edici, desteklenen bir çözüm sağlamadığı bir sorundur.

Bu konudaki gönderilerde dolaşan çok sayıda çapraz niyet ve yanlış anlama var, bu yüzden lütfen yanıt vermeden önce bu cevabın tamamını okuyun.

Aşağıda, bu sayfadaki diğer yanıtlardan gelen saldırının daha "rafine" ve iyi yorumlanmış bir versiyonunu ekliyorum, ayrıca bu çok yakından ilgili sorulardan gelen fikirleri de dahil ediyorum:

Android menüsünün arka plan rengini değiştirin

Seçenekler menüsünün arka plan rengi nasıl değiştirilir?

Android: uygulamanın menüsünü özelleştirin (örneğin arka plan rengi)

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

Android MenuItem Geçiş Düğmesi

Android seçenekleri menüsü arka planını yarı saydam yapmak mümkün müdür?

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

Menü arka planını opak olacak şekilde ayarlama

Bu hack'i 2.1 (simülatör), 2.2 (2 gerçek cihaz) ve 2.3 (2 gerçek cihaz) üzerinde test ettim. Henüz test etmek için 3.X tabletim yok, ancak varsa / yaparsam gerekli değişiklikleri burada yayınlayacağım. 3.X tabletlerin, burada açıklandığı gibi Seçenekler Menüleri yerine İşlem Çubukları kullandığı göz önüne alındığında:

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

bu hack, 3.X tabletlerde neredeyse kesinlikle hiçbir şey yapmayacaktır (zarar ve yararı yoktur).

SORUNUN AÇIKLAMASI (olumsuz bir yorumla tetikleyici yanıtlamadan önce bunu okuyun):

Seçenekler menüsü, farklı cihazlarda çok farklı stillere sahiptir. Bazılarında beyaz metin bulunan saf siyah, bazılarında siyah metin olan saf beyaz. Ben ve diğer birçok geliştirici, Seçenekler menüsü hücrelerinin arka plan rengini ve Seçenekler menüsü metninin rengini kontrol etmek istiyor .

Bazı uygulama geliştiricilerinin yalnızca hücre arka plan rengini (metin rengini değil) ayarlaması gerekir ve bunu başka bir yanıtta açıklanan android: panelFullBackground stilini kullanarak daha temiz bir şekilde yapabilirler. Bununla birlikte, şu anda Seçenekler menüsünün metin rengini stillerle kontrol etmenin bir yolu yoktur ve bu nedenle, bu yöntem yalnızca arka planı metni "kaybolmayacak" başka bir renge dönüştürmek için kullanılabilir.

Bunu belgelenmiş, geleceğe yönelik bir çözümle yapmayı çok isteriz, ancak Android <= 2.3'ten itibaren mevcut değildir. Bu nedenle, mevcut sürümlerde çalışan ve gelecek sürümlerde çökme / kırılma olasılığını en aza indirmek için tasarlanmış bir çözüm kullanmalıyız. Başarısız olması gerekiyorsa, sorunsuz bir şekilde varsayılan davranışa geri dönen bir çözüm istiyoruz.

Seçenekler menülerinin görünümünü kontrol etmenin gerekmesinin birçok geçerli nedeni vardır (tipik olarak uygulamanın geri kalanı için görsel bir stille eşleştirmek için), bu yüzden bunun üzerinde durmayacağım.

Bununla ilgili yayınlanan bir Google Android hatası var: lütfen bu hataya yıldız ekleyerek desteğinizi ekleyin (Google'ın "ben de" yorumlarından vazgeçtiğini unutmayın: sadece bir yıldız yeterlidir):

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

Şimdiye kadarki ÇÖZÜMLERİN ÖZETİ:

Birkaç poster, LayoutInflater.Factory'yi içeren bir hack önerdi. Önerilen hack Android <= 2.2 için çalıştı ve Android 2.3 için başarısız oldu çünkü hack belgelenmemiş bir varsayım yaptı: aynı LayoutInflater örneğinde LayoutInflater.inflate () çağrısının içinde olmadan LayoutInflater.getView () 'u çağırabilirdi. Android 2.3'teki yeni kod, bu varsayımı bozdu ve NullPointerException'a yol açtı.

Aşağıdaki biraz rafine edilmiş hack'im bu varsayıma dayanmıyor.

Ayrıca, hackler ayrıca dahili, belgelenmemiş bir sınıf adı olan "com.android.internal.view.menu.IconMenuItemView" 'u bir dize olarak (bir Java türü olarak değil) kullanmaya dayanır. Bundan kaçınmanın bir yolunu görmüyorum ve yine de belirtilen hedefi gerçekleştiriyorum. Ancak, mevcut sistemde "com.android.internal.view.menu.IconMenuItemView" görünmüyorsa geri dönecek dikkatli bir şekilde kesmek mümkündür.

Yine, bunun bir hack olduğunu anlayın ve hiçbir şekilde bunun tüm platformlarda çalışacağını iddia etmiyorum. Ancak biz geliştiriciler, her şeyin kitapta olması gereken fantastik bir akademik dünyada yaşamıyoruz: çözmemiz gereken bir sorun var ve onu elimizden geldiğince çözmeliyiz. Örneğin, Seçenekler Menüleri yerine Eylem Çubukları kullandıklarından, "com.android.internal.view.menu.IconMenuItemView" öğesinin 3.X tabletlerde bulunması olası görünmüyor.

Son olarak, bazı geliştiriciler bu sorunu Android Seçenekler Menüsünü tamamen kapatarak ve kendi menü sınıflarını yazarak çözdüler (yukarıdaki bağlantılardan bazılarına bakın). Bunu denemedim, ancak kendi Görünümünüzü yazmak ve Android'in görünümünü nasıl değiştireceğinizi bulmak için zamanınız varsa (eminim burada ayrıntılarda şeytan da vardır), o zaman bu herhangi bir gerektirmeyen güzel bir çözüm olabilir belgelenmemiş hackler.

HİLE:

İşte kod.

Bu kodu kullanmak için onCreate () etkinliğinizden veya onCreateOptionsMenu () etkinliğinizden addOptionsMenuHackerInflaterFactory () 'yi çağırın. Herhangi bir Seçenek Menüsünün daha sonra oluşturulmasını etkileyecek varsayılan bir fabrika ayarlar. Zaten oluşturulmuş Seçenekler Menülerini etkilemez (önceki hackler setMenuBackground () işlev adını kullanıyordu, bu işlev geri dönmeden önce herhangi bir menü özelliğini ayarlamadığından bu çok yanıltıcıdır).

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

Okuduğunuz için teşekkürler ve keyfini çıkartın!


15
Bunu (ve benzer çözümü) kullanmaya çalışırken güvenilir bir şekilde elde ettiğim tek şey `java.lang.IllegalStateException: Bu LayoutInflater'da zaten bir fabrika ayarlandı '
Bostone

Benim için çalışıyor! Sonunda bir çözüme sahip olmak çok güzel! Gingerbread, Honeycomb ve ICS üzerinde test edildi
Chad Schultz

Samsung Galaxy Nexus (4.1.1) ile test edildi ve çalışıyor! İyi mal Louis!
Felipe Caldas

2
Galaxy Nexus 7'de (4.1.1) çalışır ancak metin rengi, ilk kez gizlendikten sonra menüye yapılan sonraki her çağrıda geri döndürülür.
Will Kru

1
IllegalStateException'ı da alıyorum. Hack, kullandığım ActionBarSherlock ile uyumsuz görünüyor.
Travis

20

Menü arka planının stil özelliği android:panelFullBackground.

Dokümantasyonun söylediğine rağmen, bir kaynak olması gerekiyor (örneğin @android:color/blackveya @drawable/my_drawable), doğrudan bir renk değeri kullanırsanız çökecektir.

Bu aynı zamanda primalpop çözümünü kullanarak değiştiremediğim veya kaldıramadığım öğe sınırlarından da kurtulacak.

Metin rengine gelince, onu 2.2'deki stiller arasında ayarlamanın bir yolunu bulamadım ve eminim her şeyi denedim (menü arka plan özelliğini bu şekilde keşfettim). Bunun için primalpop'un çözümünü kullanmanız gerekir.


3
Bu değeri nerede ayarlamalıyım? Android 2.2'de çalışmasını sağlayamadım. veya 2.3
Janusz

1
@ Janusz içinde Styles.xml. Bu muhtemelen yardımcı olacaktır: developer.android.com/guide/topics/resources/…
Pilot_51

2
Çalışmıyor, nereye gitmesi gerektiğini söylerseniz güzel, menü öğelerime atıfta bulunmak için başka bir stil yapmak dışında her yerde denediyseniz .....
John

14

Android 2.3 için bu, çok ağır bir bilgisayar korsanlığı ile yapılabilir:

Android 2.3 ile ilgili sorunların temel nedeni, LayoutInflater'da mConstructorArgs [0] = mContext'in yalnızca çağrıları çalıştırırken ayarlanmasıdır.

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'te çalışmasını ve hala önceki sürümlerde çalışmasını test ettim. Daha sonraki Android sürümlerinde herhangi bir şey tekrar bozulursa, bunun yerine varsayılan menü stilini görürsünüz.


Bu kod yalnızca 2.1 sürümüne kadar çalışır Bu kod daha iyi görünüyor: stackoverflow.com/questions/2944244/…
Felipe Caldas

Merhaba, işlevinizi kullandım ama şu hatayı aldım: com.android.internal.view.menu.IconMenuItemView sınıfını şişirirken hata oluştu ve sonra bir istisna daha <unknown> sınıfını şişirme hatası ... şimdi ne yapmalıyım ... ? Lütfen bana yardım et.
Rushabh Patel

13

Gingerbread ile uyumlu olması ve hala Holo özellikli cihazların stilini olabildiğince fazla tutması gereken bir Uygulamada bu sorunla karşılaştım.

Benim için iyi çalışan nispeten temiz bir çözüm buldum.

Temada, özel bir arka plan rengi elde etmek için 9 yama çizilebilir bir arka plan kullanıyorum:

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

Metin renginin stilini belirlemeye çalışmaktan vazgeçtim ve kodda öğemin metin rengini ayarlamak için Spannable kullandım:

@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;
}

Gingerbread cihazında ActionBarSherlock Light temasını kullanma sorunum için harika çalışıyor! Bununla, seçenekler menüsü arka planını açık griye ve metin rengini siyaha kolayca değiştirebilirim (Simgeler zaten
ActionBar'da

13

Benimkini böyle çözdüm. Sadece arka plan rengini ve metin rengini stillerde belirledim. yani res> değerler> styles.xml dosyası.

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

1
metin rengi her yerde değişir
user3156040

Sadece ürün arka plan rengini değiştirir ve menü seçeneği düzeni üst ve alt dolgu vardır, yardım etmez
FarshidABZ

10

Unutulmaması gereken bir şey de, diğer birçok gönderi gibi sorunu aşırı karmaşık hale getiriyorsunuz! Tek yapmanız gereken, ihtiyacınız olan arka planlara sahip çekilebilir seçiciler oluşturmak ve bunları gerçek öğelere ayarlamaktır. Çözümlerinizi denemek için sadece iki saat harcadım (tümü bu sayfada önerildi) ve hiçbiri işe yaramadı. Sahip olduğunuz deneme / yakalama bloklarında esasen performansınızı yavaşlatan tonlarca hata olduğundan bahsetmiyorum bile.

Her neyse, işte bir menü xml dosyası:

<?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>

Şimdi item1_selector'ınızda:

<?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>

Bir dahaki sefere Kanada üzerinden süpermarkete gitmeye karar verdiğinizde google maps'i deneyin!


Tamamen katılıyorum. O =) zaten varken neden Android'i yeniden icat etmelisiniz?
Fredrik

Harika çalışıyor. Simgeniz ve istediğiniz arka planla bir katman listesi oluştur Tek sorun, metin rengini değiştirip değiştiremeyeceğimi bilmemem. Bu nedenle her arka plan rengi işe yaramaz
Janusz

53
Güzel, zarif ve konuyu tamamen çözmüyor.
Aea

1
Yanılmıyorsam, bu sadece simgenin arka planını değiştiriyor, beyaz kalan menü öğesinin kendisini değil.
Jrom

3
Bu soru sorusu değil. Bu tamamen farklı bir düşünce.
Kostadin

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

bu benim için iyi çalışıyor


başlık rengi nasıl değiştirilir
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
Lütfen bunu yapmayın: name.equalsIgnoreCase ("com.android.internal.view.menu.IconMenuItemView" Adından da anlaşılacağı gibi, bu özel uygulama ayrıntılarını kullanır ve bu nedenle herhangi bir platform güncellemesinde veya cihazda
bozulabilir

1
IconMenuItemView, temel View sınıfından türetilen seçenekler menüsünü oluşturan ve kontrol eden sınıftır. Bu sınıf android kaynak kodundandır ve en azından api sürüm 5'ten beri mevcuttur. Herhangi bir platform güncellemesinde veya cihazda kırıldığını göremiyorum.
Primal Pappachan

1
Göremiyorsun çünkü geleceği göremiyorsun. Emin olmanın bir yolu olsa bile, bu kötü bir uygulamadır
HXCaine

Teşekkürler, bu bir tutam için yararlıdır. Ancak, onCreateOptionsMenu'da oluşturulan öğeler gibi özel durumlarda çalışmaz, ancak onPrepareOptionsMenu'da devre dışı bırakılır, ancak daha sonra tekrar etkinleştirilir.
HRJ

3

Teşekkürler Marcus! Bazı sözdizimi hatalarını düzelterek 2.3 üzerinde sorunsuz çalışır, işte sabit kod

    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
Bunun için aldığım tek şey: java.lang.IllegalStateException: Bu LayoutInflater'da bir fabrika zaten kurulmuş
Bostone

ActionBarSherlock ve uyumluluk çerçevesi ile çalışmasını sağlamak ve IllegalStateException'dan kaçınmak için bu hileye bakın 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;
        }
    });
}

bu XML dosyası

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

1

Rasgele bir renk ayarlamak istiyorsanız, bu oldukça iyi çalışıyor gibi görünüyor androidx. KitKat ve Pie üzerinde test edilmiştir. Bunu şuraya koy 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);
}

Bu android.widget.PopupWindow$PopupBackgroundView, tahmin edebileceğiniz gibi arka plan rengini çizen rengini ayarlar . Fazla çizim yoktur ve yarı saydam renkleri de kullanabilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.