วิธีการเปลี่ยนสีข้อความของรายการเมนูใน Android


175

ฉันสามารถเปลี่ยนสีพื้นหลังของรายการเมนูใน Android ได้หรือไม่

โปรดแจ้งให้เราทราบหากใครมีวิธีแก้ไขปัญหานี้ ตัวเลือกสุดท้ายจะเห็นได้ชัดว่ากำหนดเอง แต่จะมีวิธีใดในการเปลี่ยนสีข้อความโดยไม่ต้องกำหนดเอง


มีใครบ้างที่สามารถแจ้งให้ฉันทราบวิธีการแก้ปัญหานี้
sunil

3
คุณต้องการเปลี่ยนสีข้อความสีพื้นหลังของมุมมองข้อความหรือไม่ หรือทั้งคู่? ทั้งสองเป็นสิ่งที่แตกต่างกัน กรุณาใส่คำถามใหม่อีกครั้ง
Abhinav Saxena

คำตอบ:


335

บรรทัดเดียวในธีมของคุณ :)

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

19
หมายเหตุ: สิ่งนี้จะต้องอยู่ในคำจำกัดความของธีมหลักสำหรับแอปของคุณไม่ใช่actionBarStyleตัวอย่างเช่น มันจะไม่ทำงานภายในactionBarStyleแม้ว่ามันจะดูสมเหตุสมผลก็ตาม!
โคลินเอ็ม

47
เพื่อรองรับเวอร์ชัน API ที่ต่ำกว่าโปรด<item name="actionMenuTextColor">@color/your_color</item>อย่าใช้เนมสเปซ Android
alex.p

5
@ColinM แต่ก็มีที่จะเข้าไปในธีม หากคุณตั้งค่าคุณลักษณะบนแถบเครื่องมือของคุณการทำงานนี้ theme
DariusL

2
ไม่ทำงานสำหรับฉันทั้งที่มีและไม่มี android: namespace มันถูกเพิ่มเข้ากับธีมหลักของแอพ
racs

2
ฉันยังคงไม่สามารถเปลี่ยนสีของข้อความได้อย่างสมบูรณ์ ชุดรูปแบบข้อความสีโดยรวมของฉันเป็นเพียงการตั้งค่า ความช่วยเหลือใด ๆ คำตอบเหล่านี้ไม่ทำงาน
David P

114

ดูเหมือนว่า

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

ในรูปแบบของฉันและ

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

in styles.xml เปลี่ยนลักษณะของ list-items แต่ไม่ใช่รายการเมนู


5
ใช้งานได้ดีสำหรับรายการเมนูบริบท (ไม่ใช่รายการเมนูจากปุ่มเมนู) ซึ่งเป็นสิ่งที่ฉันกำลังมองหา ง่ายกว่าเลอะ LayoutFactory ทั้งหมด
chubbsondubs

android:itemTextAppearanceแอตทริบิวต์ไม่สามารถวางไว้ในรูปแบบที่มีผู้ปกครองparent="@android:style/Widget.Holo.ListPopupWindow"มาตั้งแต่ปีที่จะไม่ทำให้ถูกต้อง android:Theme.Holo.Light.DarkActionBarมันจะต้องเป็นในสไตล์ระดับบนสุดอย่างหนึ่งที่มีผู้ปกครอง
toobsco42

ฉันควรเพิ่ม <item name = "android: itemTextAppearance"> @ style / myCustomMenuTextApearance </item> ที่ไหน
Bagusflyer

@bagusflyer คุณควรเพิ่มว่าในรูปแบบรากของธีมของคุณคือสไตล์ที่เป็นลูกของTheme.HoloหรือTheme.Holo.Light.DarkActionBarหรือคล้ายกัน
Tash Pemhiwa

86

คุณสามารถเปลี่ยนสีของMenuItemข้อความได้อย่างง่ายดายโดยใช้แทนSpannableStringString

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

10
สิ่งนี้ใช้ได้กับฉันทั้งใน 4.4 และ 5+ โดยใช้menu.findItem(R.id.menu_item_id);แทนmenu.getItem()
haagmm

1
ทำงานให้ฉันด้วย [ใช้ findItem (... )]
งงงวย

6
โซลูชันใช้งานได้เฉพาะรายการที่มีมากเกิน .... ฉันไม่ต้องการเปลี่ยนสีของรายการที่มองเห็นได้ด้วยการตั้งค่า showAsAction: "เสมอ"
Junaid

56

หากคุณใช้ Toolbar ใหม่ด้วยธีมTheme.AppCompat.Light.NoActionBarคุณสามารถจัดรูปแบบได้ตามวิธีต่อไปนี้

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

ตามผลลัพธ์ที่ฉันได้รับ
android:textColorPrimaryคือสีข้อความที่แสดงชื่อกิจกรรมของคุณซึ่งเป็นข้อความหลักของแถบเครื่องมือ

android:textColorSecondaryเป็นสีข้อความสำหรับปุ่มคำบรรยายและตัวเลือกเพิ่มเติม (3 จุด) (ใช่มันเปลี่ยนสีตามคุณสมบัตินี้!)

android:textColorเป็นสีสำหรับข้อความอื่นทั้งหมดรวมถึงเมนู

ในที่สุดตั้งค่าชุดรูปแบบเป็นแถบเครื่องมือ

<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"/>

รายการใดที่ควบคุมข้อความบนปุ่มที่แสดงเป็นการกระทำ (ข้อความ) บนแถบเครื่องมือ ทั้ง android: textColorPrimary, android: textColorSecondary และ android: textColor ดูเหมือนจะส่งผลกระทบต่อพวกเขา
LarsH

ตอบคำถามของฉันในความคิดเห็นก่อนหน้านี้: android:actionMenuTextColor(ดูstackoverflow.com/a/5538709/423105 )
LarsH

32

หากคุณใช้เมนู<android.support.design.widget.NavigationView />จากนั้นเพิ่มบรรทัดด้านล่างในNavigationView:

app:itemTextColor="your color"

นอกจากนี้ยังมี colorTint สำหรับไอคอนมันจะแทนที่สีสำหรับไอคอนของคุณเช่นกัน เพื่อที่คุณจะต้องเพิ่มบรรทัดด้านล่าง:

app:itemIconTint="your color"

ตัวอย่าง:

<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"/>

หวังว่ามันจะช่วยคุณ


สิ่งนี้เปลี่ยนไอเท็มที่ซ้อนในไอเท็มอื่น แต่ไม่ได้เปลี่ยนไอเท็มที่มีไอเท็มอื่น คุณรู้หรือไม่ว่าฉันสามารถเปลี่ยนได้อย่างไร
Dinu Nicolae

@DinuNicolae คุณช่วยกรุณาโพสต์ภาพหน้าจอตัวอย่างของคุณได้ไหม? หรือให้รายละเอียดเพิ่มเติม
Mihir Trivedi

ฉันมี <item> <menu> <รายการภายใน> </menu> </item> และมีเพียงสีของไอเท็มที่เปลี่ยนแปลงภายใน
Dinu Nicolae

31

ฉันไปเกี่ยวกับมันโดยทางโปรแกรมเช่นนี้:

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

2
คำตอบของคุณช่วยให้ฉันตั้งค่าข้อความเมนูเป็นตัวหนา (s.setSpan (StyleSpan ใหม่ (android.graphics.Typeface.BOLD), 0, s.length (), 0); ขอบคุณ!
Arkadiusz Cieśliński

วิธีนี้ช่วยแก้ไขปัญหาของฉันได้ ฉันชอบสิ่งนี้เพราะมันจะไม่ขึ้นอยู่กับรูปแบบที่สัมพันธ์กัน
Tomcat

15

อย่างที่คุณเห็นในคำถามนี้คุณควร:

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

โค้ดด้านบนเปลี่ยนสีข้อความของรายการแอ็คชันเมนูสำหรับ API> = v21

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

ด้านบนเป็นรหัสสำหรับ API <v21


ขอบคุณ. สิ่งนี้ควรได้รับการยอมรับ มันง่ายและสะดวก
Pooja

10

ฉันใช้แท็ก html เพื่อเปลี่ยนสีข้อความของรายการเดียวเมื่อรายการเมนูขยายเกินจริง หวังว่ามันจะเป็นประโยชน์

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

1
สิ่งนี้ใช้ไม่ได้กับฉันใน Marshmallow ข้อความถูกนำไปใช้ แต่ไม่ใช่สี
Ollie C

เกี่ยวกับ Marshmallow อาจจะไม่ได้ด้วยเหตุผลเดียวกันกับที่ระบุไว้ในคำตอบของ max.mustermann "โซลูชันใช้ได้กับสินค้าในล้นเท่านั้น"
Jose_GD

10

วิธีที่ง่ายที่สุดในการสร้างสีเมนูที่กำหนดเองสำหรับแถบเครื่องมือเดียวไม่ใช่สำหรับ 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>

แถบเครื่องมือปกติบน styles.xml

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

สไตล์แถบเครื่องมือที่กำหนดเองของเรา

<style name="AppTheme.AppBarOverlay.MenuBlue">
    <item name="actionMenuTextColor">@color/blue</item>
</style>

ใช้งานได้ดี! คำตอบที่ดีที่สุด
bebe

9

ใน Kotlin ฉันเขียนส่วนขยายเหล่านี้:

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

และใช้ดังนี้:

menu.findItem(R.id.main_settings).setTitleColor(Color.RED)

ชอบวิธีนี้มาก ๆ !
Jamil Nawaz

ขอบคุณวิธีแก้ปัญหาที่ง่ายและรวดเร็ว สำหรับ API> 24 มันจะทำงานโดยไม่มีฟังก์ชั่น ext ที่สอง
laszlo

7

คำตอบสั้น ๆ คือใช่ โชคดีนะคุณ!
หากต้องการทำเช่นนั้นคุณจะต้องแทนที่สไตล์บางอย่างของสไตล์เริ่มต้นของ Android:

ก่อนอื่นให้ดูคำจำกัดความของธีมใน 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>

ดังนั้นการปรากฏตัวของข้อความในเมนูอยู่ใน@android:style/TextAppearance.Widget.IconMenu.Item
ตอนนี้ในการกำหนดรูปแบบ :

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

ดังนั้นตอนนี้เรามีชื่อของสีที่เป็นปัญหาถ้าคุณดูในโฟลเดอร์สีของทรัพยากรของระบบ:

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

ในที่สุดนี่คือสิ่งที่คุณต้องทำ:

แทนที่ "TextAppearance.Widget.IconMenu.Item" และสร้างสไตล์ของคุณเอง จากนั้นลิงก์ไปยังตัวเลือกของคุณเองเพื่อให้เป็นแบบที่คุณต้องการ หวังว่านี่จะช่วยคุณได้ โชคดี!


ขอบคุณที่ตอบกลับ ฉันได้ทำสิ่งที่คุณแนะนำ แต่มันไม่ได้เปลี่ยนสีของรายการเมนู
sunil

ที่จริงแล้วฉันเพิ่งรู้จากการอ่านเมนูสิ่งต่าง ๆ ที่มันซับซ้อนกว่าที่ฉันคิดไว้มากถ้าคุณไม่ต้องการสร้างเมนูแบบเต็มของคุณเอง ... นี่จะต้องมีการอ่านเพิ่มเติมสำหรับฉันฉันจะเก็บไว้ คุณโพสต์ที่นี่หากฉันพบมากขึ้น
Sephy

ไม่สามารถแทนที่ "TextAppearance.Widget.IconMenu.Item"
peceps

คำตอบนี้ทำให้เข้าใจผิด .. ดังนั้นข้อสรุปก็คือมันไม่ทำงานและยากมาก / นานที่จะบรรลุมากกว่าที่คิดไว้เดิม?
speedynomads

6

เมนูตัวเลือกใน android สามารถปรับแต่งเพื่อตั้งค่าพื้นหลังหรือเปลี่ยนลักษณะข้อความ ไม่สามารถเปลี่ยนพื้นหลังและสีข้อความในเมนูโดยใช้ธีมและสไตล์ ซอร์สโค้ด Android (data \ res \ layout \ icon_menu_item_layout.xml) ใช้รายการที่กำหนดเองของคลาส“ com.android.internal.view.menu.IconMenuItem” ดูสำหรับโครงร่างเมนู เราสามารถทำการเปลี่ยนแปลงในคลาสข้างต้นเพื่อปรับแต่งเมนู เพื่อให้บรรลุเดียวกันใช้ LayoutInflater ระดับโรงงานและตั้งค่าพื้นหลังและสีข้อความสำหรับมุมมอง


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



3
03-23 19:45:25.134: E/AndroidRuntime(26761): java.lang.IllegalStateException: A factory has already been set on this LayoutInflater
ถึงกระ

ใช้งานได้เป็นครั้งแรก เมื่อคุณเปิดเมนูเป็นครั้งที่สองคุณจะได้รับการยกเว้น
LoveForDroid

6

ขอบคุณสำหรับตัวอย่างโค้ด ฉันต้องแก้ไขมันไปให้มันใช้งานได้กับเมนูบริบท นี่คือทางออกของฉัน

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

สำหรับฉันมันใช้งานได้กับ Android 1.6, 2.03 และ 4.03


หากคุณทำสิ่งข้างต้นคุณควรดูการใช้โซลูชัน Marcus Wolschon ง่ายกว่ามาก
chubbsondubs

โซลูชัน xml ใช้งานไม่ได้สำหรับฉันเช่น 2.3.x แต่มันใช้งานได้ดีเช่นมีเสน่ห์ - เช่นเดียวกับ 4.x
sunlock

วิธีนี้ใช้ได้ผลดีที่สุด ฉันต้องจับ android.support.v7.internal.view.menu.ListMenuItemView เพื่อให้ได้รูปแบบที่ใช้กับอุปกรณ์ที่ใช้ไลบรารีที่เข้ากันได้
Chiatar

การแก้ไขนี้จะไม่ทำงานกับ Google Maps v2 - วิธีซุปเปอร์จะต้องเรียกว่า 1 เพื่อให้แผนที่แสดงผลได้อย่างถูกต้อง
Chiatar

5

ฉันพบมันยูเรก้า !!

ในธีมแอพของคุณ:

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

นี่คือชุดรูปแบบแถบการกระทำของคุณ:

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

และนี่คือธีมป๊อปอัพของคุณ:

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

ไชโย;)


5

เพื่อเปลี่ยนสีข้อความของรายการเมนูใช้รหัสด้านล่าง

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

ที่ไหน

<style name="menu_item_color">
<item name="android:textColor">@color/app_font_color</item>
</style>

4

ขอบคุณ max.musterman นี่เป็นวิธีแก้ปัญหาที่ฉันได้ทำงานในระดับ 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.BLACKอาจกลายเป็นพารามิเตอร์เพิ่มเติมสำหรับsetMenuTextColorวิธีการ android:showAsAction="never"นอกจากนี้ผมใช้เพียงแค่นี้สำหรับรายการเมนูที่มี


ไม่ทำงานกับฉันใน API 24 ความคิดใด ๆ เคยติดอยู่กับเรื่องนี้มาหลายวันแล้ว ... ไร้สาระ!
David P

ไม่แน่ใจว่าจะบอกอะไรคุณ นี่ใช้งานได้ดีสำหรับฉันใน API 25
lightkeeper

3

คุณสามารถตั้งค่าสีโดยทางโปรแกรม

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

        }
    });
}

3

การเพิ่มสิ่งนี้ลงในสไตล์ของฉัน

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

2

เพียงเพิ่มสิ่งนี้ลงในธีมของคุณ

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

ทดสอบกับ API 21


2
มันดีกว่าที่จะใช้<style name="AppTheme.ItemTextStyle" parent="@android:style/TextAppearance.Widget">มิฉะนั้นข้อความจะปรากฏเล็กเกินไปในเมนูโอเวอร์โฟลว์ โปรดทราบว่าเทคนิคนี้ใช้งานได้กับ Android 5 ขึ้นไปเท่านั้น
Mr-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

1
อธิบายคำตอบของคุณ
Coder

1
ถ้าไม่ใช่ SearchView ล่ะ?
nasch

2

สถานการณ์ของฉันคือการตั้งค่าสีข้อความในเมนูตัวเลือก (เมนูแอพหลักแสดงบนปุ่มเมนูกด)

การทดสอบในAPI 16กับAppCompat-v7-27.0.2ห้องสมุดAppCompatActivityสำหรับการMainActivityและAppCompatรูปแบบสำหรับการประยุกต์ใช้ใน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>

ไม่ทราบว่าจะtextColorSecondaryมีผลกับองค์ประกอบอื่นหรือไม่ แต่จะควบคุมสีข้อความของเมนู


ฉันค้นหาตัวอย่างบางส่วนในหัวข้อ แต่ตัวอย่างข้อมูลแบบพร้อมใช้งานทั้งหมดไม่ทำงาน

ดังนั้นฉันต้องการตรวจสอบด้วยซอร์สโค้ดสำหรับไลบรารี appcompat-v7 (โดยเฉพาะกับโฟลเดอร์resของแพ็คเกจ. aar )

แม้ว่าในกรณีของฉันฉันใช้ Eclipse กับการพึ่งพา. explar ดังนั้นฉันสามารถเปลี่ยนสไตล์เริ่มต้นและตรวจสอบผลลัพธ์ ไม่ทราบวิธีการระเบิดไลบรารีที่จะใช้กับGradleหรือAndroid Studioโดยตรง มันสมควรได้รับการสอบสวนอีกครั้ง

ดังนั้นจุดประสงค์ของฉันคือหาสีใดในไฟล์res / values ​​/ values.xml ที่ใช้สำหรับข้อความเมนู (ฉันเกือบแน่ใจว่าสีอยู่ที่นั่น)

  1. ฉันเปิดไฟล์นั้นจากนั้นทำซ้ำทุกสีวางไว้ใต้ค่าเริ่มต้นเพื่อแทนที่และกำหนด #f00ค่าให้กับพวกเขาทั้งหมด
  2. เริ่มแอพ
  3. องค์ประกอบหลายอย่างมีพื้นหลังสีแดงหรือสีข้อความ และรายการเมนูด้วย นั่นคือสิ่งที่ฉันต้องการ
  4. การลบสีที่เพิ่มของฉันโดยบล็อกของ 5-10 บรรทัดฉันจบลงด้วยการ secondary_text_default_material_lightรายการสี
  5. การค้นหาชื่อนั้นในไฟล์ภายในโฟลเดอร์res (หรือดีกว่าในres / colours ) ฉันพบการเกิดขึ้นเพียงครั้งเดียวในcolor / abc_secondary_text_material_light.xml (ฉันใช้ Sublime Text สำหรับการดำเนินการเหล่านี้ดังนั้นจึงง่ายต่อการค้นหาสิ่งที่ฉันต้องการ)
  6. กลับไปที่ประเพณีx.xml 8 พบว่าสำหรับ@color/abc_secondary_text_material_lightประเพณีถูกพบสำหรับ
  7. มันเป็นชุดรูปแบบอ่อนดังนั้นเหลือ 4 ใน 2 ชุดรูปแบบ: Base.ThemeOverlay.AppCompat.LightและPlatform.AppCompat.Lightและ
  8. รูปแบบแรกคือลูกของคนที่สองจึงมีเพียง 2 คุณลักษณะที่มีทรัพยากรสี: android:textColorSecondaryและในandroid:textColorTertiaryBase.ThemeOverlay.AppCompat.Light
  9. การเปลี่ยนค่าของพวกเขาโดยตรงในvalues.xmlและใช้ app android:textColorSecondaryที่ผมพบว่าแอตทริบิวต์ที่ถูกต้องสุดท้ายคือ
  10. ต่อไปฉันต้องการธีมหรือแอททริบิวอื่นเพื่อที่ฉันจะสามารถเปลี่ยนได้ในstyle.xmlของแอ (เพราะธีมของฉันมีเป็นพาเรนต์Theme.AppCompat.Lightและไม่ใช่ThemeOverlay.AppCompat.Light )
  11. Base.ThemeOverlay.AppCompat.Lightฉันค้นหาในไฟล์เดียวสำหรับ มันมีลูกThemeOverlay.AppCompat.Lightมันมีบุตร
  12. ค้นหาThemeOverlay.AppCompat.Lightฉันพบการใช้งานในBase.Theme.AppCompat.Light.DarkActionBarชุดรูปแบบเป็นactionBarPopupThemeค่าแอตทริบิวต์
  13. ธีมของแอพของฉันTheme.AppCompat.Light.DarkActionBarเป็นลูกของการค้นพบBase.Theme.AppCompat.Light.DarkActionBarดังนั้นฉันสามารถใช้คุณลักษณะนั้นในstyles.xmlของฉันได้โดยไม่มีปัญหา
  14. ตามที่เห็นในโค้ดตัวอย่างด้านบนฉันสร้างธีมลูกจากที่กล่าวถึงThemeOverlay.AppCompat.Lightและเปลี่ยนandroid:textColorSecondaryคุณลักษณะ

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


1

โซลูชันของ Sephyไม่ทำงาน เป็นไปได้ที่จะแทนที่การปรากฏตัวของรายการเมนูตัวเลือกโดยใช้วิธีการที่อธิบายไว้ข้างต้น แต่ไม่ใช่รายการหรือเมนู ในการทำเช่นนั้นมี 3 วิธี:

  1. จะเปลี่ยนสีพื้นหลังของเมนูตัวเลือกได้อย่างไร?
  2. เขียนมุมมองของคุณเองเพื่อแสดงและแทนที่ onCreateOptionsMenu และ onPrepareOptionsMenu เพื่อรับผลลัพธ์ที่คุณต้องการ ฉันระบุสิ่งนี้โดยทั่วไปเพราะคุณสามารถทำสิ่งที่คุณต้องการในวิธีการเหล่านี้ได้โดยทั่วไป แต่คุณอาจไม่ต้องการโทรหา super ()
  3. คัดลอกรหัสจาก SDK โอเพ่นซอร์สและปรับแต่งสำหรับพฤติกรรมของคุณ การใช้งานเมนูเริ่มต้นที่ใช้โดยกิจกรรมจะไม่ใช้อีกต่อไป

ดูที่ปัญหา 4441: ธีมเมนูตัวเลือกที่กำหนดเองสำหรับเบาะแสเพิ่มเติม


ในการยืนยันซ้ำ ... โซลูชันของ Sephy ใช้งานได้กับรายการเมนู TextAppearance ถึงแม้ว่าสิ่งที่ฉันทำไปแล้วจะแทนที่ค่าเริ่มต้นผ่าน themes.xml นอกจากนี้ # 2 หรือ # 3 ข้างต้นควรทราบว่าการโทรไปที่ super # onCreateOptionsMenu / super # onPrepareOptionsMenu ถูกออกแบบมาเพื่อวางรายการเมนูระบบ ... ตามที่ระบุใน javadoc สำหรับกิจกรรม # onCreateOptionsMenu () นั่นอาจ / อาจไม่สำคัญสำหรับแอปของคุณ
หวงแหน

สิ่งที่ Sephy กำลังอธิบายคือการมีสิ่งนี้ใน themes.xml ของคุณ: <item name = "android: itemTextAppearance"> @ style / Text_MenuItemText </item> จากนั้นกำหนดบางอย่างเช่นนี้ใน styles.xml ของคุณ: <style name = "Text_MenuItemText" > <item name = "android: textSize"> 12dp </item> <item name = "android: textColor"> # FFFFFF </item> </style> นั้นง่ายมาก ๆ นั่นคือสิ่งที่คุณหมายถึงอะไร การปรับแต่งเมนูตัวเลือกที่ลึกลงไปนั้นไม่ใช่เรื่องง่าย แต่ฉันตั้งใจจะโพสต์บทความบล็อกเกี่ยวกับเรื่องนี้ในไม่ช้า
หวงแหน

1

ลองรหัสนี้ ....

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

1
บน Android> 4.0 ฉันได้รับjava.lang.IllegalStateException: A factory has already been set on this LayoutInflater
ถึง Kra

1

หากคุณต้องการตั้งค่าสีสำหรับรายการเมนูแต่ละรายการการปรับแต่งธีมของแถบเครื่องมือไม่ใช่วิธีที่เหมาะสม เพื่อให้บรรลุนี้คุณสามารถใช้ android: actionLayout และมุมมองแอ็คชั่นสำหรับรายการเมนู

ขั้นแรกให้สร้างไฟล์เลย์เอาต์ XML สำหรับมุมมองการกระทำ ในตัวอย่างนี้เราใช้ปุ่มเป็นมุมมองการกระทำ:

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>

ในข้อมูลโค้ดข้างต้นเราใช้android:textColor="?android:attr/colorAccent"ในการปรับแต่งสีข้อความของปุ่ม

จากนั้นในไฟล์ XML เลย์เอาต์ของคุณสำหรับเมนูรวมapp:actionLayout="@layout/menu_button"ดังต่อไปนี้:

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>

แทนที่onCreateOptionsMenu()วิธีการล่าสุดในกิจกรรมของคุณ:

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

... หรือส่วน:

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

สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับมุมมองการกระทำดูคู่มือนักพัฒนาซอฟต์แวร์ Android


0

นี่คือวิธีที่คุณสามารถสีรายการเมนูเฉพาะด้วยสีใช้งานได้กับทุกระดับ 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));
                                }
                            }
                        }
                    }
                });
            }
        }
    }
}

ด้วยการทำเช่นนั้นคุณทำให้เอฟเฟ็กเตอร์ตัวเลือกพื้นหลังหลวมนี่คือรหัสที่จะใช้ตัวเลือกพื้นหลังแบบกำหนดเองกับรายการเมนูลูกทั้งหมด

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

นี่คือฟังก์ชันตัวช่วยด้วย:

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

0

สำหรับการเปลี่ยนสีของข้อความคุณสามารถตั้งค่ามุมมองแบบกำหนดเองสำหรับ MenuItem จากนั้นคุณสามารถกำหนดสีของข้อความ

รหัสตัวอย่าง: MenuItem.setActionView ()


ในขณะที่ข้อมูลโค้ดนี้อาจแก้ไขคำถามรวมถึงคำอธิบายช่วยปรับปรุงคุณภาพของโพสต์ของคุณ จำไว้ว่าคุณกำลังตอบคำถามสำหรับผู้อ่านในอนาคตและคนเหล่านั้นอาจไม่ทราบสาเหตุของการแนะนำรหัสของคุณ
Mischa
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.