Bagaimana cara mengubah warna Teks item Menu di Android?

175

Bisakah saya mengubah warna latar belakang item Menu di Android?

Tolong beri tahu saya jika ada yang punya solusi untuk ini. Opsi terakhir jelas akan menyesuaikannya tetapi apakah ada cara untuk mengubah warna teks tanpa mengubahnya.

sunil
sumber
Adakah yang bisa memberi tahu saya solusinya?
sunil
3
Anda ingin mengubah warna teks, warna latar belakang tampilan teks? atau keduanya? Keduanya adalah hal yang berbeda. Harap bingkai ulang pertanyaannya.
Abhinav Saxena

Jawaban:

335

Satu baris sederhana di tema Anda :)

<item name="android:actionMenuTextColor">@color/your_color</item>
Muhammad Alfaifi
sumber
19
CATATAN: Ini HARUS masuk dalam definisi Tema utama untuk aplikasi Anda, BUKAN dalam actionBarStylemisalnya. Ini tidak akan berfungsi di dalam actionBarStyle, meskipun itu tampak logis!
Colin M.
47
Untuk mendukung versi API yang lebih rendah, <item name="actionMenuTextColor">@color/your_color</item>jangan gunakan namespace Android
alex.p
5
@ColinM. Hal ini untuk masuk ke sebuah tema. Jika Anda menetapkan themeatribut pada bilah alat, ini berfungsi.
DariusL
2
Tidak bekerja untuk saya baik dengan atau tanpa android: namespace. Itu ditambahkan ke tema aplikasi utama.
Pembalap
2
Saya masih sepenuhnya tidak dapat mengubah warna teks. Warna teks tema keseluruhan saya hanya membutuhkan preferensi. Ada bantuan? Tidak satu pun dari jawaban ini yang berfungsi.
David P
114

Tampaknya sebuah

  <item name="android:itemTextAppearance">@style/myCustomMenuTextAppearance</item>

dalam tema saya dan

   <style name="myCustomMenuTextAppearance" parent="@android:style/TextAppearance.Widget.IconMenu.Item">
        <item name="android:textColor">@android:color/primary_text_dark</item>
    </style>

di styles.xml ubah gaya item daftar tetapi bukan item menu.

Marcus Wolschon
sumber
5
Ini berfungsi baik untuk item menu konteks (bukan item menu dari tombol menu) yang saya cari. Jauh lebih sederhana daripada seluruh kekacauan LayoutFactory.
chubbsondubs
The android:itemTextAppearanceatribut tidak dapat ditempatkan dalam gaya yang induknya adalah parent="@android:style/Widget.Holo.ListPopupWindow"karena itu tidak akan tersaji dengan baik. Itu harus dalam gaya tingkat atas seperti yang orang tuanya android:Theme.Holo.Light.DarkActionBar.
toobsco42
Di mana saya harus menambahkan <item name = "android: itemTextAppearance"> @ style / myCustomMenuTextApearance </item>?
Bagusflyer
@bagusflyer Anda harus menambahkan bahwa dalam gaya akar tema Anda, yaitu gaya yang adalah anak Theme.Holoatau Theme.Holo.Light.DarkActionBaratau serupa.
Tash Pemhiwa
86

Anda dapat mengubah warna MenuItemteks dengan mudah menggunakan SpannableStringbukan String.

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.your_menu, menu);

    int positionOfMenuItem = 0; // or whatever...
    MenuItem item = menu.getItem(positionOfMenuItem);
    SpannableString s = new SpannableString("My red MenuItem");
    s.setSpan(new ForegroundColorSpan(Color.RED), 0, s.length(), 0);
    item.setTitle(s);
}
max.mustermann
sumber
10
Ini bekerja untuk saya baik dalam 4.4 dan 5+ menggunakan menu.findItem(R.id.menu_item_id);bukanmenu.getItem()
haagmm
1
Bekerja untuk saya juga [menggunakan findItem (...)].
Bingung
6
solusi hanya berfungsi untuk item yang melimpah .... saya tidak dapat mengubah warna item yang terlihat dengan menyetel showAsAction: "always"
Junaid
56

Jika Anda menggunakan Bilah Alat baru, dengan tema Theme.AppCompat.Light.NoActionBar, Anda dapat menatanya dengan cara berikut.

 <style name="ToolbarTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:textColorPrimary">@color/my_color1</item>
    <item name="android:textColorSecondary">@color/my_color2</item>
    <item name="android:textColor">@color/my_color3</item>
 </style>`

Menurut hasil yang saya dapatkan,
android:textColorPrimaryadalah warna teks yang menampilkan nama aktivitas Anda, yang merupakan teks utama dari toolbar.

android:textColorSecondaryadalah warna teks untuk tombol subtitle dan lebih banyak opsi (3 titik). (Ya, warnanya berubah sesuai dengan properti ini!)

android:textColorAdalah warna untuk semua teks lainnya termasuk menu.

Akhirnya atur tema ke Toolbar

<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:theme="@style/ToolbarTheme"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:minHeight="?attr/actionBarSize"/>
Sudara
sumber
Item mana yang mengatur teks pada tombol yang ditampilkan sebagai tindakan (teks) pada bilah alat? Baik android: textColorPrimary, android: textColorSecondary, maupun android: textColor tampaknya memengaruhi mereka.
LarsH
Sebagai jawaban atas pertanyaan saya di komentar sebelumnya: android:actionMenuTextColor(lihat stackoverflow.com/a/5538709/423105 ).
LarsH
32

Jika Anda menggunakan menu saat <android.support.design.widget.NavigationView />itu tambahkan saja baris di bawah ini di NavigationView:

app:itemTextColor="your color"

Juga tersedia colorTint untuk ikon, itu akan menimpa warna untuk ikon Anda juga. Untuk itu Anda harus menambahkan baris di bawah ini:

app:itemIconTint="your color"

Contoh:

<android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"

        app:itemTextColor="@color/color_white"
        app:itemIconTint="@color/color_white"

        android:background="@color/colorPrimary"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer"/>

Semoga ini bisa membantu Anda.

Mihir Trivedi
sumber
Ini mengubah item yang bersarang di item lain, tetapi itu tidak mengubah item yang mengandung item lain. Apakah Anda tahu bagaimana saya bisa mengubahnya juga?
Dinu Nicolae
@DinuNicolae Bisakah Anda memposting tangkapan layar contoh Anda? Atau berikan lebih detail.
Mihir Trivedi
Saya memiliki <item> <menu> <item dalam> </menu> </item> dan hanya warna item di dalamnya yang berubah
Dinu Nicolae
31

Saya menjalankannya secara terprogram seperti ini:

public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.changeip_card_menu, menu); 
    for(int i = 0; i < menu.size(); i++) {
        MenuItem item = menu.getItem(i);
        SpannableString spanString = new SpannableString(menu.getItem(i).getTitle().toString());
        spanString.setSpan(new ForegroundColorSpan(Color.BLACK), 0,     spanString.length(), 0); //fix the color to white
        item.setTitle(spanString);
    }
    return true;
}
Muralikrishna GS
sumber
2
jawaban Anda membantu saya mengatur teks MenuItem menjadi tebal. (s.setSpan (StyleSpan baru (android.graphics.Typeface.BOLD), 0, s.length (), 0); Terima kasih!
Arkadiusz Cieśliński
Solusi ini membantu masalah saya. Saya suka ini karena itu tidak akan tergantung pada condtions yang dirilis tema.
Tomcat
15

seperti yang Anda lihat dalam pertanyaan ini, Anda harus:

<item name="android:textColorPrimary">yourColor</item>

Kode di atas mengubah warna teks item tindakan menu untuk API> = v21.

<item name="actionMenuTextColor">@android:color/holo_green_light</item>

Di atas adalah kode untuk API <v21

Pouya Danesh
sumber
Terima kasih. Ini harus diterima. Sederhana dan mudah
Pooja
10

Saya menggunakan tag html untuk mengubah warna teks satu item ketika item menu meningkat. Semoga bermanfaat.

public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    menu.findItem(R.id.main_settings).setTitle(Html.fromHtml("<font color='#ff3824'>Settings</font>"));
    return true;
}
alijandro
sumber
1
Ini tidak berfungsi untuk saya di Marshmallow. Teks diterapkan, tetapi bukan warnanya.
Ollie C
Mengenai Marshmallow, mungkin itu tidak berfungsi karena alasan yang sama yang dinyatakan dalam jawaban max.mustermann, "solusi hanya berfungsi untuk item yang meluap."
Jose_GD
10

Cara SIMPLEST untuk membuat warna menu kustom untuk bilah alat tunggal, bukan untuk AppTheme

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay.MenuBlue">
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"/>
    </android.support.design.widget.AppBarLayout>

toolbar biasa di styles.xml

<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/>

gaya bilah alat kustom kami

<style name="AppTheme.AppBarOverlay.MenuBlue">
    <item name="actionMenuTextColor">@color/blue</item>
</style>
AndrewS
sumber
Bagus sekali! Jawaban Terbaik.
bebe
9

di Kotlin saya menulis ekstensi ini:

fun MenuItem.setTitleColor(color: Int) {
    val hexColor = Integer.toHexString(color).toUpperCase().substring(2)
    val html = "<font color='#$hexColor'>$title</font>"
    this.title = html.parseAsHtml()
}           



@Suppress("DEPRECATION")                                                                        
fun String.parseAsHtml(): Spanned {                                                             
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {                                
        Html.fromHtml(this, Html.FROM_HTML_MODE_LEGACY)                                         
    } else {                                                                                    
        Html.fromHtml(this)                                                                     
    }                                                                                           
}  

dan digunakan seperti ini:

menu.findItem(R.id.main_settings).setTitleColor(Color.RED)
Amir Khorsandi
sumber
Sangat suka solusi ini, sangat rapi!
Jamil Nawaz
Terima kasih, solusi sederhana dan cepat. Untuk API> 24 berfungsi tanpa fungsi ext kedua
laszlo
7

Jawaban singkatnya adalah YA. Beruntunglah anda!
Untuk melakukannya, Anda perlu mengganti beberapa gaya gaya default Android:

Pertama, lihat definisi tema di Android:

<style name="Theme.IconMenu">
<!-- Menu/item attributes -->
<item name="android:itemTextAppearance">@android:style/TextAppearance.Widget.IconMenu.Item</item>
<item name="android:itemBackground">@android:drawable/menu_selector</item>
<item name="android:itemIconDisabledAlpha">?android:attr/disabledAlpha</item>
<item name="android:horizontalDivider">@android:drawable/divider_horizontal_bright</item>
<item name="android:verticalDivider">@android:drawable/divider_vertical_bright</item>
<item name="android:windowAnimationStyle">@android:style/Animation.OptionsPanel</item>
<item name="android:moreIcon">@android:drawable/ic_menu_more</item>
<item name="android:background">@null</item>
</style>

Jadi, tampilan teks dalam menu ada di @android:style/TextAppearance.Widget.IconMenu.Item
Sekarang, dalam definisi gaya :

<style name="TextAppearance.Widget.IconMenu.Item" parent="TextAppearance.Small">
<item name="android:textColor">?textColorPrimaryInverse</item>
</style>

Jadi sekarang kita memiliki nama warna yang dimaksud, jika Anda melihat di folder warna sumber daya sistem:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="@android:color/bright_foreground_light_disabled" /> 
<item android:state_window_focused="false" android:color="@android:color/bright_foreground_light" /> 
<item android:state_pressed="true" android:color="@android:color/bright_foreground_light" /> 
<item android:state_selected="true" android:color="@android:color/bright_foreground_light" /> 
<item android:color="@android:color/bright_foreground_light" /> 
<!--  not selected --> 
</selector>

Akhirnya, inilah yang perlu Anda lakukan:

Ganti "TextAppearance.Widget.IconMenu.Item" dan buat gaya Anda sendiri. Kemudian tautkan ke pemilih Anda sendiri untuk membuatnya seperti yang Anda inginkan. Semoga ini bisa membantu Anda. Semoga berhasil!

Sephy
sumber
Terima kasih telah membalas. Saya telah melakukan apa yang Anda sarankan tetapi tidak mengubah warna item menu
sunil
Sebenarnya, saya baru sadar dengan membaca lebih banyak hal menu bahwa itu jauh lebih rumit daripada yang saya kira. Jika Anda tidak ingin membuat menu kustom lengkap sendiri ... Ini akan membutuhkan lebih banyak bacaan untuk saya, saya akan teruskan Anda diposting di sini jika saya menemukan lebih banyak.
Sephy
Tidak mungkin menimpa "TextAppearance.Widget.IconMenu.Item".
peceps
Jawaban ini menyesatkan .. jadi kesimpulannya, itu tidak bekerja dan jauh lebih sulit / panjang untuk mencapai daripada yang diperkirakan?
speedynomads
6

Menu opsi di android dapat disesuaikan untuk mengatur latar belakang atau mengubah tampilan teks. Latar belakang dan warna teks dalam menu tidak dapat diubah menggunakan tema dan gaya. Kode sumber android (data \ res \ layout \ icon_menu_item_layout.xml) menggunakan item khusus dari kelas "com.android.internal.view.menu.IconMenuItem" Lihat untuk tata letak menu. Kita dapat membuat perubahan di kelas di atas untuk menyesuaikan menu. Untuk mencapai hal yang sama, gunakan kelas pabrik LayoutInflater dan atur warna latar belakang dan teks untuk tampilan.


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.my_menu, menu);
    getLayoutInflater().setFactory(new Factory() {
        @Override
        public View onCreateView(String name, Context context, AttributeSet attrs) {
            if (name .equalsIgnoreCase(“com.android.internal.view.menu.IconMenuItemView”)) {
                try{
                    LayoutInflater f = getLayoutInflater();
                    final View view = f.createView(name, null, attrs);
                    new Handler().post(new Runnable() {
                        public void run() {
                            // set the background drawable
                            view .setBackgroundResource(R.drawable.my_ac_menu_background);

                            // set the text color
                            ((TextView) view).setTextColor(Color.WHITE);
                        }
                    });
                    return view;
                } catch (InflateException e) {
                    } catch (ClassNotFoundException e) {}
            }
            return null;
        }
    });
    return super.onCreateOptionsMenu(menu);
}


Abhay Kumar
sumber
3
03-23 19:45:25.134: E/AndroidRuntime(26761): java.lang.IllegalStateException: A factory has already been set on this LayoutInflater
Ke Kra
Ini bekerja untuk pertama kalinya. Ketika Anda membuka menu untuk kedua kalinya Anda mendapatkan pengecualian.
LoveForDroid
6

Terima kasih untuk contoh kode. Saya harus memodifikasinya, mulai bekerja dengan menu konteks. Ini solusi saya.

    static final Class<?>[] constructorSignature = new Class[] {Context.class, AttributeSet.class};

class MenuColorFix implements LayoutInflater.Factory {
    public View onCreateView(String name, Context context, AttributeSet attrs) {
        if (name.equalsIgnoreCase("com.android.internal.view.menu.ListMenuItemView")) {
            try {
                Class<? extends ViewGroup> clazz = context.getClassLoader().loadClass(name).asSubclass(ViewGroup.class);
                Constructor<? extends ViewGroup> constructor = clazz.getConstructor(constructorSignature);
                final ViewGroup view = constructor.newInstance(new Object[]{context,attrs});

                new Handler().post(new Runnable() {
                    public void run() {
                        try {
                            view.setBackgroundColor(Color.BLACK);
                            List<View> children = getAllChildren(view);
                            for(int i = 0; i< children.size(); i++) {
                                View child = children.get(i);
                                if ( child instanceof TextView ) {
                                    ((TextView)child).setTextColor(Color.WHITE);
                                }
                            }
                        }
                        catch (Exception e) {
                            Log.i(TAG, "Caught Exception!",e);
                        }

                    }
                });
                return view;
            }
            catch (Exception e) {
                Log.i(TAG, "Caught Exception!",e);
            }
        }
        return null;
    }       
}

public List<View> getAllChildren(ViewGroup vg) {
    ArrayList<View> result = new ArrayList<View>();
    for ( int i = 0; i < vg.getChildCount(); i++ ) {
        View child = vg.getChildAt(i);
        if ( child instanceof ViewGroup) {
            result.addAll(getAllChildren((ViewGroup)child));
        }
        else {
            result.add(child);
        }
    }
    return result;
}

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
    LayoutInflater lInflater = getLayoutInflater();
    if ( lInflater.getFactory() == null ) {
        lInflater.setFactory(new MenuColorFix());
    }
    super.onCreateContextMenu(menu, v, menuInfo);
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.myMenu, menu);
}

Bagi saya ini bekerja dengan Android 1.6, 2.03 dan 4.03.

Michael Vogl
sumber
Jika Anda melakukan hal di atas maka Anda harus melihat menggunakan solusi Marcus Wolschon. Jauh lebih sederhana.
chubbsondubs
Solusi xml tidak bekerja untuk saya pada misalnya 2.3.x, tetapi ini berfungsi seperti pesona - juga pada 4.x
sunlock
Solusi ini bekerja paling baik. Saya juga harus menangkap android.support.v7.internal.view.menu.ListMenuItemView untuk mendapatkan gaya yang diterapkan pada perangkat menggunakan perpustakaan kompatibilitas
Chiatar
Perbaikan ini tidak akan bekerja dengan Google Maps v2 - metode super harus disebut 1st agar peta dibuat dengan benar.
Chiatar
5

saya menemukannya Eureka !!

dalam tema aplikasi Anda:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:actionBarStyle">@style/ActionBarTheme</item>
    <!-- backward compatibility -->          
    <item name="actionBarStyle">@style/ActionBarTheme</item>        
</style>

inilah tema bar tindakan Anda:

<style name="ActionBarTheme" parent="@style/Widget.AppCompat.Light.ActionBar.Solid.Inverse">
   <item name="android:background">@color/actionbar_bg_color</item>
   <item name="popupTheme">@style/ActionBarPopupTheme</item
   <!-- backward compatibility -->
   <item name="background">@color/actionbar_bg_color</item>
</style>

dan di sini adalah tema munculan Anda:

 <style name="ActionBarPopupTheme">
    <item name="android:textColor">@color/menu_text_color</item>
    <item name="android:background">@color/menu_bg_color</item>
 </style>

Bersulang ;)

Fareed Alnamrouti
sumber
5

untuk mengubah warna teks item menu gunakan kode di bawah ini

<style name="AppToolbar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:itemTextAppearance">@style/menu_item_color</item>
</style>

dimana

<style name="menu_item_color">
<item name="android:textColor">@color/app_font_color</item>
</style>
Muhammad Abdullah
sumber
4

Berkat max.musterman, ini adalah solusi yang saya dapat gunakan di level 22:

public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main, menu);
    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    MenuItem searchMenuItem = menu.findItem(R.id.search);
    SearchView searchView = (SearchView) searchMenuItem.getActionView();
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setSubmitButtonEnabled(true);
    searchView.setOnQueryTextListener(this);
    setMenuTextColor(menu, R.id.displaySummary, R.string.show_summary);
    setMenuTextColor(menu, R.id.about, R.string.text_about);
    setMenuTextColor(menu, R.id.importExport, R.string.import_export);
    setMenuTextColor(menu, R.id.preferences, R.string.settings);
    return true;
}

private void setMenuTextColor(Menu menu, int menuResource, int menuTextResource) {
    MenuItem item = menu.findItem(menuResource);
    SpannableString s = new SpannableString(getString(menuTextResource));
    s.setSpan(new ForegroundColorSpan(Color.BLACK), 0, s.length(), 0);
    item.setTitle(s);
}

Hardcoded Color.BLACKbisa menjadi parameter tambahan untuk setMenuTextColormetode ini. Juga, saya hanya menggunakan ini untuk item menu yang sebelumnya android:showAsAction="never".

penjaga cahaya
sumber
Tidak bekerja untuk saya di API 24. Ada gagasan? Terjebak selama berhari-hari ... konyol!
David P
Tidak yakin harus memberi tahu Anda apa. Ini berfungsi dengan baik untuk saya di API 25.
lightkeeper
3

Anda dapat mengatur warna secara terprogram.

private static void setMenuTextColor(final Context context, final Toolbar toolbar, final int menuResId, final int colorRes) {
    toolbar.post(new Runnable() {
        @Override
        public void run() {
            View settingsMenuItem =  toolbar.findViewById(menuResId);
            if (settingsMenuItem instanceof TextView) {
                if (DEBUG) {
                    Log.i(TAG, "setMenuTextColor textview");
                }
                TextView tv = (TextView) settingsMenuItem;
                tv.setTextColor(ContextCompat.getColor(context, colorRes));
            } else { // you can ignore this branch, because usually there is not the situation
                Menu menu = toolbar.getMenu();
                MenuItem item = menu.findItem(menuResId);
                SpannableString s = new SpannableString(item.getTitle());
                s.setSpan(new ForegroundColorSpan(ContextCompat.getColor(context, colorRes)), 0, s.length(), 0);
                item.setTitle(s);
            }

        }
    });
}
Victor Choy
sumber
3

Menambahkan ini ke styles.xml saya berfungsi untuk saya

<item name="android:textColorPrimary">?android:attr/textColorPrimaryInverse</item>
Asim
sumber
2

Cukup tambahkan ini ke tema Anda

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:itemTextAppearance">@style/AppTheme.ItemTextStyle</item>
</style>

<style name="AppTheme.ItemTextStyle" parent="@android:style/TextAppearance.Widget.IconMenu.Item">
        <item name="android:textColor">@color/orange_500</item>
</style>

Diuji pada API 21

Pham Quan
sumber
2
Lebih baik digunakan <style name="AppTheme.ItemTextStyle" parent="@android:style/TextAppearance.Widget">, jika tidak, teks muncul terlalu kecil di menu melimpah. Perhatikan juga bahwa teknik ini hanya berfungsi pada Android 5 dan di atasnya.
Bp-IDE
2
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.search, menu);


    MenuItem myActionMenuItem = menu.findItem( R.id.action_search);
    SearchView searchView = (SearchView) myActionMenuItem.getActionView();

    EditText searchEditText = (EditText) searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
    searchEditText.setTextColor(Color.WHITE); //You color here
Bāda
sumber
1
jelaskan jawaban Anda
Coder
1
Bagaimana jika itu bukan SearchView?
nasch
2

Situasi saya adalah pengaturan warna teks di menu opsi (menu aplikasi utama ditampilkan pada tombol menu tekan).

Diuji dalam API 16 dengan pustaka appcompat-v7-27.0.2 , AppCompatActivityuntuk MainActivitydan AppCompattema untuk aplikasi di AndroidManifest.xml .

styles.xml :

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
  <item name="actionBarPopupTheme">@style/PopupTheme</item>
</style>

<style name="PopupTheme" parent="@style/ThemeOverlay.AppCompat.Light">
  <item name="android:textColorSecondary">#f00</item>
</style>

Tidak tahu apakah itu textColorSecondarymemengaruhi elemen lain tetapi itu mengontrol warna teks menu.


Saya mencari beberapa contoh tentang topik ini tetapi semua cuplikan yang siap pakai tidak berfungsi.

Jadi saya ingin menyelidikinya dengan kode sumber untuk appcompat-v7 (khusus dengan folder res dari paket .aar ).

Meskipun dalam kasus saya, saya menggunakan Eclipse dengan meledak .aar dependensi . Jadi saya bisa mengubah gaya default dan memeriksa hasilnya. Tidak tahu cara meledakkan perpustakaan untuk digunakan dengan Gradle atau Android Studio secara langsung. Itu layak utas investigasi lainnya.

Jadi tujuan saya adalah mencari warna di file res / values ​​/ values.xml yang digunakan untuk teks menu (saya hampir yakin warnanya ada di sana).

  1. Saya membuka file itu, lalu menggandakan semua warna, meletakkannya di bawah yang standar untuk menimpanya dan ditugaskan #f00 nilai pada semuanya.
  2. Mulai aplikasi.
  3. Banyak elemen memiliki latar belakang merah atau warna teks. Dan item menu juga. Itulah yang saya butuhkan.
  4. Menghapus warna yang ditambahkan oleh blok 5-10 garis saya akhiri dengan secondary_text_default_material_light item warna.
  5. Mencari nama itu di file dalam folder res (atau lebih baik dalam res / warna ) Saya hanya menemukan satu kejadian di warna / abc_secondary_text_material_light.xml (saya menggunakan Teks Sublime untuk operasi ini sehingga lebih mudah untuk menemukan hal yang saya butuhkan).
  6. Kembali ke values.xml 8 penggunaan ditemukan untuk@color/abc_secondary_text_material_light .
  7. Itu adalah tema Cahaya jadi 4 tersisa dalam 2 tema: Base.ThemeOverlay.AppCompat.LightdanPlatform.AppCompat.Light .
  8. Tema pertama adalah anak dari yang kedua sehingga hanya ada 2 atribut dengan sumber daya warna itu: android:textColorSecondarydan android:textColorTertiarydi Base.ThemeOverlay.AppCompat.Light.
  9. Mengubah nilai mereka langsung di values.xml dan menjalankan aplikasi saya menemukan bahwa atribut yang benar adalahandroid:textColorSecondary .
  10. Selanjutnya saya membutuhkan tema atau atribut lain sehingga saya bisa mengubahnya di style.xml aplikasi saya (karena tema saya memiliki sebagai induk Theme.AppCompat.Lightdan bukanThemeOverlay.AppCompat.Light ).
  11. Saya mencari di file yang sama untuk Base.ThemeOverlay.AppCompat.Light. Itu punya anakThemeOverlay.AppCompat.Light .
  12. Mencari ThemeOverlay.AppCompat.LightSaya menemukan penggunaannya dalam Base.Theme.AppCompat.Light.DarkActionBartema sebagaiactionBarPopupTheme atribut.
  13. Tema aplikasi saya Theme.AppCompat.Light.DarkActionBaradalah anak dari yang ditemukan Base.Theme.AppCompat.Light.DarkActionBarsehingga saya dapat menggunakan atribut itu di styles.xml saya tanpa masalah.
  14. Seperti yang terlihat pada contoh kode di atas saya membuat tema anak dari yang disebutkan ThemeOverlay.AppCompat.Lightdan mengubah android:textColorSecondaryatribut.

https://i.imgur.com/LNfKdzC.png

mortalis
sumber
1

Solusi Sephy tidak bekerja. Dimungkinkan untuk menimpa tampilan teks item menu pilihan menggunakan metode yang dijelaskan di atas, tetapi tidak item atau menu. Untuk melakukan itu pada dasarnya ada 3 cara:

  1. Bagaimana cara mengubah warna latar belakang menu opsi?
  2. Tulis tampilan Anda sendiri untuk ditampilkan dan timpa onCreateOptionsMenu dan onPrepareOptionsMenu untuk mendapatkan hasil yang Anda inginkan. Saya menyatakan ini secara umum karena Anda biasanya dapat melakukan apa pun yang Anda inginkan dalam metode ini, tetapi Anda mungkin tidak ingin memanggil super ().
  3. Salin kode dari SDK sumber terbuka dan sesuaikan dengan perilaku Anda. Implementasi menu default yang digunakan oleh Activity tidak lagi berlaku.

Lihat Edisi 4441: Tema Menu Opsi Kustom untuk petunjuk lebih lanjut.

Gigih
sumber
Untuk mengulangi ... Solusi Sephy berfungsi untuk item menu TextAppearance, meskipun apa yang saya lakukan adalah menimpa default melalui themes.xml. Juga, # 2 atau # 3 di atas harus menyadari bahwa memanggil ke super # onCreateOptionsMenu / super # onPrepareOptionsMenu dirancang untuk menempatkan item menu sistem ... seperti yang ditunjukkan dalam javadoc untuk Kegiatan # onCreateOptionsMenu (). Itu mungkin / mungkin tidak masalah bagi aplikasi Anda.
Tenacious
Yang dijelaskan Sephy adalah memiliki ini di themes.xml Anda: <item name = "android: itemTextAppearance"> @ style / Text_MenuItemText </item> Kemudian tentukan sesuatu seperti ini di styles.xml: <style name = "Text_MenuItemText" > <item name = "android: textSize"> 12dp </item> <item name = "android: textColor"> # FFFFFF </item> </style> Itu semudah yang didapat. Apakah itu yang kamu maksud? Kustomisasi opsi-menu yang lebih dalam sama sekali tidak mudah, tetapi saya bermaksud untuk segera memposting artikel blog tentang hal itu.
Tenacious
1

coba kode ini ....

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

        getLayoutInflater().setFactory(new Factory() {
            @Override
            public View onCreateView(String name, Context context,
                    AttributeSet attrs) {

                if (name.equalsIgnoreCase("com.android.internal.view.menu.IconMenuItemView")) {
                    try {
                        LayoutInflater f = getLayoutInflater();
                        final View view = f.createView(name, null, attrs);

                        new Handler().post(new Runnable() {
                            public void run() {

                                // set the background drawable
                                 view.setBackgroundResource(R.drawable.my_ac_menu_background);

                                // set the text color
                                ((TextView) view).setTextColor(Color.WHITE);
                            }
                        });
                        return view;
                    } catch (InflateException e) {
                    } catch (ClassNotFoundException e) {
                    }
                }
                return null;
            }
        });
        return super.onCreateOptionsMenu(menu);
    }
Anoop
sumber
1
di Android> 4.0 saya mulaijava.lang.IllegalStateException: A factory has already been set on this LayoutInflater
Ke Kra
1

Jika Anda ingin mengatur warna untuk masing-masing item menu, menyesuaikan tema toolbar bukanlah solusi yang tepat. Untuk mencapai ini, Anda dapat menggunakan android: actionLayout dan tampilan tindakan untuk item menu.

Pertama buat file tata letak XML untuk tampilan tindakan. Dalam contoh ini kami menggunakan tombol sebagai tampilan aksi:

menu_button.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/menuButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Done"
        android:textColor="?android:attr/colorAccent"
        style="?android:attr/buttonBarButtonStyle"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Dalam cuplikan kode di atas, kami menggunakan android:textColor="?android:attr/colorAccent" untuk menyesuaikan warna teks tombol.

Kemudian dalam file tata letak XML Anda untuk menu, sertakan app:actionLayout="@layout/menu_button" seperti yang ditunjukkan di bawah ini:

main_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/menuItem"
        android:title=""
        app:actionLayout="@layout/menu_button"
        app:showAsAction="always"/>
</menu>

Terakhir timpa onCreateOptionsMenu()metode dalam aktivitas Anda:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main_menu, menu);
    MenuItem item = menu.findItem(R.id.menuItem);
    Button saveButton = item.getActionView().findViewById(R.id.menuButton);
    saveButton.setOnClickListener(view -> {
        // Do something
    });
    return true;
}

... atau fragmen:

@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater){
    inflater.inflate(R.menu.main_menu, menu);
    MenuItem item = menu.findItem(R.id.menuItem);
    Button saveButton = item.getActionView().findViewById(R.id.menuButton);
    button.setOnClickListener(view -> {
        // Do something
    });
}

Untuk detail lebih lanjut tentang tampilan tindakan, lihat panduan pengembang Android .

Alexander Poleschuk
sumber
0

Ini adalah bagaimana Anda dapat mewarnai item menu tertentu dengan warna, berfungsi untuk semua level API:

public static void setToolbarMenuItemTextColor(final Toolbar toolbar,
                                               final @ColorRes int color,
                                               @IdRes final int resId) {
    if (toolbar != null) {
        for (int i = 0; i < toolbar.getChildCount(); i++) {
            final View view = toolbar.getChildAt(i);
            if (view instanceof ActionMenuView) {
                final ActionMenuView actionMenuView = (ActionMenuView) view;
                // view children are accessible only after layout-ing
                actionMenuView.post(new Runnable() {
                    @Override
                    public void run() {
                        for (int j = 0; j < actionMenuView.getChildCount(); j++) {
                            final View innerView = actionMenuView.getChildAt(j);
                            if (innerView instanceof ActionMenuItemView) {
                                final ActionMenuItemView itemView = (ActionMenuItemView) innerView;
                                if (resId == itemView.getId()) {
                                    itemView.setTextColor(ContextCompat.getColor(toolbar.getContext(), color));
                                }
                            }
                        }
                    }
                });
            }
        }
    }
}

Dengan melakukan itu Anda kehilangan efek pemilih latar belakang, jadi di sini adalah kode untuk menerapkan pemilih latar belakang kustom untuk semua item menu anak-anak.

public static void setToolbarMenuItemsBackgroundSelector(final Context context,
                                                         final Toolbar toolbar) {
    if (toolbar != null) {
        for (int i = 0; i < toolbar.getChildCount(); i++) {
            final View view = toolbar.getChildAt(i);
            if (view instanceof ImageButton) {
                // left toolbar icon (navigation, hamburger, ...)
                UiHelper.setViewBackgroundSelector(context, view);
            } else if (view instanceof ActionMenuView) {
                final ActionMenuView actionMenuView = (ActionMenuView) view;

                // view children are accessible only after layout-ing
                actionMenuView.post(new Runnable() {
                    @Override
                    public void run() {
                        for (int j = 0; j < actionMenuView.getChildCount(); j++) {
                            final View innerView = actionMenuView.getChildAt(j);
                            if (innerView instanceof ActionMenuItemView) {
                                // text item views
                                final ActionMenuItemView itemView = (ActionMenuItemView) innerView;
                                UiHelper.setViewBackgroundSelector(context, itemView);

                                // icon item views
                                for (int k = 0; k < itemView.getCompoundDrawables().length; k++) {
                                    if (itemView.getCompoundDrawables()[k] != null) {
                                        UiHelper.setViewBackgroundSelector(context, itemView);
                                    }
                                }
                            }
                        }
                    }
                });
            }
        }
    }
}

Berikut adalah fungsi pembantu:

public static void setViewBackgroundSelector(@NonNull Context context, @NonNull View itemView) {
    int[] attrs = new int[]{R.attr.selectableItemBackgroundBorderless};
    TypedArray ta = context.obtainStyledAttributes(attrs);
    Drawable drawable = ta.getDrawable(0);
    ta.recycle();

    ViewCompat.setBackground(itemView, drawable);
}
kotak
sumber
0

Untuk mengubah warna teks, Anda bisa mengatur tampilan kustom untuk MenuItem, dan kemudian Anda bisa menentukan warna untuk teks.

Kode Sampel: MenuItem.setActionView ()

waktu luang
sumber
Sementara potongan kode ini dapat menyelesaikan pertanyaan, termasuk penjelasan sangat membantu untuk meningkatkan kualitas posting Anda. Ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa depan, dan orang-orang itu mungkin tidak tahu alasan untuk saran kode Anda.
Mischa