Làm cách nào để thay đổi màu Văn bản của mục Menu trong Android?


175

Tôi có thể thay đổi màu nền của một mục Menu trong Android không?

Xin vui lòng cho tôi biết nếu có ai có bất kỳ giải pháp cho việc này. Tùy chọn cuối cùng rõ ràng là để tùy chỉnh nó, nhưng có cách nào để thay đổi màu văn bản mà không tùy chỉnh nó.


Có ai có thể cho tôi biết giải pháp cho việc này không?
nắng

3
Bạn có muốn thay đổi màu văn bản, màu nền của văn bản không? hoặc cả hai? Cả hai đều là những thứ khác nhau. Vui lòng đóng khung lại câu hỏi.
Abhinav Saxena

Câu trả lời:


335

Một dòng đơn giản trong chủ đề của bạn :)

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

19
LƯU Ý: Điều này PHẢI đi trong định nghĩa Chủ đề chính cho ứng dụng của bạn, KHÔNG trong actionBarStyleví dụ. Nó sẽ không hoạt động trong actionBarStyle, mặc dù điều đó có vẻ hợp lý!
Colin M.

47
Để hỗ trợ các phiên bản API thấp hơn, <item name="actionMenuTextColor">@color/your_color</item>không sử dụng không gian tên Android
alex.p

5
@ColinM. Nó phải đi vào một chủ đề. Nếu bạn đặt một themethuộc tính trên thanh công cụ của bạn, điều này hoạt động.
DariusL

2
Không làm việc cho tôi dù có hay không có Android: không gian tên. Nó đã được thêm vào chủ đề ứng dụng chính.
cuộc đua

2
Tôi vẫn hoàn toàn không thể thay đổi màu văn bản. Textcolor chủ đề tổng thể của tôi chỉ cần ưu tiên. Có ai giúp đỡ không? Không có câu trả lời nào trong số này hoạt động.
David P

114

Có vẻ như một

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

trong chủ đề của tôi và

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

trong tệp style.xml thay đổi kiểu của các mục danh sách nhưng không phải các mục menu.


5
Điều này hoạt động tuyệt vời cho các mục menu ngữ cảnh (không phải các mục menu từ nút menu), đó là những gì tôi đang tìm kiếm. Đơn giản hơn nhiều so với toàn bộ messFactory lộn xộn.
chubbsondub

Các android:itemTextAppearancethuộc tính không thể được đặt trong một phong cách mà cha mẹ là parent="@android:style/Widget.Holo.ListPopupWindow"vì đó sẽ không hoàn trả đúng. Nó phải ở trong một phong cách cấp cao nhất giống như một người có cha mẹ là android:Theme.Holo.Light.DarkActionBar.
toobsco42

Tôi nên thêm <item name = "android: itemTextAppparent"> @ style / myCustomMothyTextApparent </ item> ở đâu?
Bagusflyer

@bagusflyer bạn nên thêm rằng theo phong cách thư mục gốc của chủ đề của bạn, tức là phong cách mà là con của Theme.Holohoặc Theme.Holo.Light.DarkActionBarhoặc tương đương.
Tash Pemhiwa

86

Bạn có thể thay đổi màu sắc của MenuItemvăn bản một cách dễ dàng bằng cách sử dụng SpannableStringthay vì 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);
}

10
Điều này làm việc cho tôi trong cả 4.4 và 5+ bằng cách sử dụng menu.findItem(R.id.menu_item_id);thay vìmenu.getItem()
haagmm

1
Làm việc cho tôi cũng vậy [sử dụng findItem (...)].
bàng hoàng

6
các giải pháp chỉ hoạt động đối với mục bị tràn .... tôi sẽ không thay đổi màu của mục có thể nhìn thấy bằng cách đặt showAsAction: "luôn luôn"
Junaid

56

Nếu bạn đang sử dụng Thanh công cụ mới, với chủ đề Theme.AppCompat.Light.NoActionBar, bạn có thể tạo kiểu theo cách sau.

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

Theo kết quả tôi nhận được,
android:textColorPrimarylà màu văn bản hiển thị tên hoạt động của bạn, là văn bản chính của thanh công cụ.

android:textColorSecondarylà màu văn bản cho phụ đề và nhiều nút tùy chọn (3 chấm). (Có, nó đã thay đổi màu theo thuộc tính này!)

android:textColorLà màu cho tất cả các văn bản khác bao gồm menu.

Cuối cùng, đặt chủ đề cho Thanh công cụ

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

Mục nào chi phối văn bản trên các nút được hiển thị dưới dạng hành động (văn bản) trên thanh công cụ? Cả android: textColorPrimary, android: textColorSecondary, hay android: textColor dường như đều ảnh hưởng đến chúng.
LarsH

Trả lời câu hỏi của tôi trong bình luận trước: android:actionMenuTextColor(xem stackoverflow.com/a/5538709/423105 ).
LarsH

31

Nếu bạn đang sử dụng menu như vậy <android.support.design.widget.NavigationView />thì chỉ cần thêm dòng dưới đây vào NavigationView:

app:itemTextColor="your color"

Cũng có sẵn colorTint cho biểu tượng, nó cũng sẽ ghi đè màu cho biểu tượng của bạn. Cho rằng bạn phải thêm dòng dưới đây:

app:itemIconTint="your color"

Thí dụ:

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

Hy vọng nó sẽ giúp bạn.


Điều này đã thay đổi các mục được lồng trong một mục khác, nhưng nó không thay đổi các mục có chứa các mục khác. Bạn có biết làm thế nào tôi có thể thay đổi chúng quá?
Dinu Nicolae

@DinuNicolae Bạn có thể vui lòng đăng ảnh chụp màn hình ví dụ của bạn không? Hoặc cung cấp thêm chi tiết.
Mihir Trivingi

Tôi đã có <item> <menu> <bên trong các mặt hàng> </ menu> </ item> và chỉ màu sắc của các mặt hàng bên trong thay đổi
Dinu Nicolae

31

Tôi đã đi về nó theo lập trình như thế này:

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
câu trả lời của bạn đã giúp tôi đặt văn bản MenuItem thành đậm. (s.setSpan (StyleSpan mới (android.graphics.Typeface.BOLD), 0, s.length (), 0); Cảm ơn!
Arkadiusz Cieśliński

Giải pháp này đã giúp vấn đề của tôi. Tôi thích điều này vì nó sẽ không phụ thuộc vào các điều khoản liên quan đến chủ đề.
Tomcat

15

như bạn có thể thấy trong câu hỏi này, bạn nên:

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

Mã ở trên thay đổi màu văn bản của các mục hành động menu cho API> = v21.

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

Trên đây là mã cho API <v21


Cảm ơn bạn. Điều này nên được chấp nhận. Thật đơn giản và dễ dàng
Pooja

10

Tôi đã sử dụng thẻ html để thay đổi màu văn bản của một mục khi mục menu bị thổi phồng. Hy vọng nó sẽ hữu ích.

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
Điều này không làm việc cho tôi trên Marshmallow. Các văn bản được áp dụng, nhưng không phải màu sắc.
Ollie C

Về Marshmallow, có lẽ nó không hoạt động vì cùng một lý do được nêu trong câu trả lời của max.mustermann, "các giải pháp chỉ hoạt động cho mục bị tràn."
Jose_GD

10

Cách SIMPLEST để tạo màu menu tùy chỉnh cho thanh công cụ duy nhất, không dành cho 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>

thanh công cụ thông thường trên Styles.xml

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

kiểu thanh công cụ tùy chỉnh của chúng tôi

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

Hoạt động tuyệt vời! Câu trả lời tốt nhất.
bebe

9

trong Kotlin tôi đã viết các phần mở rộng này:

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

và được sử dụng như thế này:

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

Thực sự thích giải pháp này, rất gọn gàng!
Jamil Nawaz

Cảm ơn, giải pháp đơn giản và nhanh chóng. Đối với API> 24, nó hoạt động mà không có chức năng mở rộng thứ hai
laszlo

7

Câu trả lời ngắn gọn là có. bạn thật may mắn!
Để làm như vậy, bạn cần ghi đè một số kiểu của kiểu mặc định của Android:

Đầu tiên, hãy xem định nghĩa của các chủ đề trong 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>

Vì vậy, sự xuất hiện của văn bản trong menu là trong @android:style/TextAppearance.Widget.IconMenu.Item
Bây giờ, trong định nghĩa của các kiểu :

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

Vì vậy, bây giờ chúng ta có tên của màu trong câu hỏi, nếu bạn nhìn vào thư mục màu của các tài nguyên của hệ thống:

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

Cuối cùng, đây là những gì bạn cần làm:

Ghi đè "TextAppurdy.Widget.IconMothy.Item" và tạo phong cách của riêng bạn. Sau đó liên kết nó với bộ chọn của riêng bạn để làm cho nó theo cách bạn muốn. Hy vọng điều này sẽ giúp bạn. Chúc may mắn!


Cảm ơn vì đã trả lời. Tôi đã thực hiện những gì bạn đề xuất nhưng nó không thay đổi màu của mục menu
sunil

Trên thực tế, tôi chỉ nhận ra bằng cách đọc thêm các công cụ trong menu rằng nó phức tạp hơn nhiều so với tôi nghĩ Nếu bạn không muốn tạo menu tùy chỉnh đầy đủ của riêng mình ... Điều này sẽ cần đọc thêm cho tôi, tôi sẽ giữ bạn đăng ở đây nếu tôi tìm thấy nhiều hơn.
Sephy

Không thể ghi đè "TextAppparent.Widget.IconMothy.Item".
peceps

Câu trả lời này là sai lệch .. vì vậy kết luận là, nó không hoạt động và khó đạt được / dài hơn nhiều so với suy nghĩ ban đầu?
speedynomads

6

Menu tùy chọn trong Android có thể được tùy chỉnh để đặt nền hoặc thay đổi giao diện văn bản. Màu nền và màu văn bản trong menu không thể thay đổi bằng chủ đề và kiểu. Mã nguồn android (data \ res \ layout \ icon_menu_item_layout.xml) sử dụng một mục tùy chỉnh của lớp com com.android.i INTERNal.view.menu.IconMothyItem chế độ xem cho bố cục menu. Chúng ta có thể thay đổi trong lớp trên để tùy chỉnh menu. Để đạt được điều tương tự, hãy sử dụng lớp nhà máy LayoutInflater và đặt màu nền và màu văn bản cho dạng xem.


@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
Tới Kra

Điều này hoạt động lần đầu tiên. Khi bạn mở menu lần thứ hai, bạn sẽ có ngoại lệ.
LoveForDroid

6

Cảm ơn ví dụ mã. Tôi đã phải sửa đổi nó để làm cho nó hoạt động với một menu ngữ cảnh. Đây là giải pháp của tôi.

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

Đối với tôi điều này hoạt động với Android 1.6, 2.03 và 4.03.


Nếu bạn đang làm như trên thì bạn chỉ nên xem xét sử dụng giải pháp Marcus Wolschon. Đơn giản hơn nhiều.
chubbsondub

Giải pháp xml không hoạt động với tôi trên ví dụ 2.3.x, nhưng giải pháp này hoạt động như một cơ duyên - cũng trên 4.x
sunlock

Giải pháp này đã làm việc tốt nhất. Tôi cũng phải chụp android.support.v7.iternal.view.menu.ListMothyItemView để có được các kiểu được áp dụng trên các thiết bị sử dụng thư viện tương thích
Chiatar

Khắc phục sự cố này sẽ không hoạt động với Google Maps v2 - siêu phương thức phải được gọi là số 1 để bản đồ hiển thị chính xác.
Chiatar

5

tôi tìm thấy nó rồi

trong chủ đề ứng dụng của bạn:

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

đây là chủ đề thanh hành động của bạn:

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

và đây là chủ đề bật lên của bạn:

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

Chúc mừng;)


5

để thay đổi màu văn bản mục menu sử dụng mã dưới đây

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

Ở đâu

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

4

Nhờ max.musterman, đây là giải pháp tôi có để làm việc ở cấp 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);
}

Mã hóa cứng Color.BLACKcó thể trở thành một tham số bổ sung cho setMenuTextColorphương thức. Ngoài ra, tôi chỉ sử dụng điều này cho các mục menu android:showAsAction="never".


Không làm việc cho tôi trên API 24. Có ý tưởng nào không? Bị mắc kẹt trong điều này trong nhiều ngày ... nực cười!
David P

Không chắc chắn những gì để nói với bạn. Điều này hoạt động tốt với tôi trong API 25.
lightkeeper

3

Bạn có thể thiết lập màu theo chương trình.

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

Việc thêm cái này vào tệp style.xml của tôi có hiệu quả với tôi

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

2

Đơn giản chỉ cần thêm nó vào chủ đề của bạn

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

Đã thử nghiệm trên API 21


2
Tốt hơn là sử dụng <style name="AppTheme.ItemTextStyle" parent="@android:style/TextAppearance.Widget">, nếu không, văn bản xuất hiện quá nhỏ trong menu tràn. Cũng lưu ý rằng kỹ thuật này chỉ hoạt động trên Android 5 trở lên.
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
giải thích câu trả lời của bạn
Coder

1
Nếu đó không phải là SearchView thì sao?
mũi

2

Tình huống của tôi là cài đặt màu văn bản trong menu tùy chọn (menu ứng dụng chính hiển thị khi nhấn nút menu).

Đã thử nghiệm trong API 16 với thư viện appcompat-v7-27.0.2 , AppCompatActivitycho MainActivityAppCompatchủ đề cho ứng dụng trong AndroidManifest.xml .

kiểu tệp :

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

Không biết nếu điều đó textColorSecondaryảnh hưởng đến các yếu tố khác nhưng nó kiểm soát màu văn bản menu.


Tôi đã tìm kiếm một số ví dụ về chủ đề này nhưng tất cả các đoạn mã sẵn sàng sử dụng đều không hoạt động.

Vì vậy, tôi muốn điều tra nó với mã nguồn cho thư viện appcompat-v7 (cụ thể là với thư mục res của gói .aar ).

Mặc dù trong trường hợp của tôi, tôi đã sử dụng Eclipse với các phụ thuộc .aar đã phát nổ . Vì vậy, tôi có thể thay đổi các kiểu mặc định và kiểm tra kết quả. Không biết cách làm nổ tung các thư viện để sử dụng trực tiếp với Gradle hoặc Android Studio . Nó xứng đáng với một chủ đề điều tra khác.

Vì vậy, mục đích của tôi là tìm màu nào trong tệp res / value / value.xml được sử dụng cho văn bản trình đơn (tôi gần như chắc chắn màu đó ở đó).

  1. Tôi đã mở tệp đó, sau đó sao chép tất cả các màu, đặt chúng bên dưới các màu mặc định để ghi đè chúng và gán #f00 giá trị cho tất cả chúng.
  2. Bắt đầu ứng dụng.
  3. Nhiều yếu tố có màu đỏ hoặc màu văn bản. Và các mục menu cũng vậy. Đó là những gì tôi cần.
  4. Xóa các màu đã thêm của tôi bằng các khối 5-10 dòng tôi đã kết thúc bằng secondary_text_default_material_lightmục màu.
  5. Tìm kiếm tên đó trong các tệp trong thư mục res (hoặc tốt hơn trong res / colors ) Tôi chỉ tìm thấy một lần xuất hiện trong tệp color / abc_secondary tựa_m vật_light.xml (Tôi đã sử dụng Sublime Text cho các thao tác này để dễ dàng tìm thấy thứ tôi cần hơn).
  6. Quay lại giá trị 8 tập tin đã được tìm thấy cho@color/abc_secondary_text_material_light .
  7. Đó là một chủ đề Ánh sáng nên 4 trái trong 2 chủ đề: Base.ThemeOverlay.AppCompat.LightPlatform.AppCompat.Light .
  8. Chủ đề đầu tiên là một đứa con của cái thứ hai nên chỉ có 2 thuộc tính với tài nguyên màu đó: android:textColorSecondaryandroid:textColorTertiarytrong Base.ThemeOverlay.AppCompat.Light.
  9. Thay đổi giá trị của chúng trực tiếp trong tệp giá trị và chạy ứng dụng Tôi thấy rằng thuộc tính chính xác cuối cùng là android:textColorSecondary.
  10. Tiếp theo, tôi cần một chủ đề hoặc một thuộc tính khác để tôi có thể thay đổi nó trong style.xml của ứng dụng của mình (vì chủ đề của tôi có vai trò là cha mẹ Theme.AppCompat.Lightchứ không phải là ThemeOverlay.AppCompat.Light).
  11. Tôi đã tìm kiếm trong cùng một tập tin cho Base.ThemeOverlay.AppCompat.Light. Nó đã có một đứa con ThemeOverlay.AppCompat.Light.
  12. Tìm kiếm ThemeOverlay.AppCompat.Lighttôi thấy việc sử dụng nó trong Base.Theme.AppCompat.Light.DarkActionBarchủ đề là actionBarPopupThemegiá trị thuộc tính.
  13. Chủ đề của ứng dụng của tôi Theme.AppCompat.Light.DarkActionBarlà một phần tử con được tìm thấy Base.Theme.AppCompat.Light.DarkActionBarđể tôi có thể sử dụng thuộc tính đó trong tệp style.xml của mình mà không gặp vấn đề gì.
  14. Như đã thấy trong mã ví dụ ở trên, tôi đã tạo một chủ đề con từ thuộc tính được đề cập ThemeOverlay.AppCompat.Lightvà thay đổi android:textColorSecondary.

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


1

Giải pháp của Sephy không hoạt động. Có thể ghi đè giao diện văn bản của mục tùy chọn bằng cách sử dụng phương pháp được mô tả ở trên, nhưng không phải là mục hoặc menu. Để làm điều đó về cơ bản có 3 cách:

  1. Làm thế nào để thay đổi màu nền của menu tùy chọn?
  2. Viết chế độ xem của riêng bạn để hiển thị và ghi đè onCreateOptionsMothy và onPrepareOptionsMothy để có kết quả bạn muốn. Tôi nói điều này nói chung bởi vì bạn thường có thể làm bất cứ điều gì bạn muốn trong các phương thức này, nhưng có lẽ bạn sẽ không muốn gọi thành super ().
  3. Sao chép mã từ SDK nguồn mở và tùy chỉnh cho hành vi của bạn. Việc thực hiện menu mặc định được sử dụng bởi Activity sẽ không còn được áp dụng.

Xem Vấn đề 4441: Chủ đề Menu Tùy chọn Tùy chỉnh để biết thêm manh mối.


Để nhắc lại ... Giải pháp của Sephy hoạt động cho mục menu TextAppparent, mặc dù những gì tôi đã làm là ghi đè mặc định thông qua chủ đề. Ngoài ra, # 2 hoặc # 3 ở trên cũng cần lưu ý rằng việc gọi qua super # onCreateOptionsMothy / super # onPrepareOptionsMothy được thiết kế để đặt các mục menu hệ thống ... như được chỉ ra trong javadoc cho Activity # onCreateOptionsMothy (). Điều đó có thể / có thể không quan trọng đối với ứng dụng của bạn.
ngoan cường

Những gì Sephy đang mô tả là có cái này trong chủ đề của bạn: <item name = "android: itemTextAppparent"> @ style / Text_MiabItemText </ item> Sau đó, hãy định nghĩa một cái gì đó như thế này trong tệp styleDB của bạn: <style name = "Text_MiabItemText" > <item name = "android: textSize"> 12dp </ item> <item name = "android: textColor"> # FFFFFF </ item> </ style> Điều đó thật dễ dàng. Đó có phải là những gì bạn có ý nghĩa? Tùy chọn menu tùy chọn sâu hơn hoàn toàn không dễ dàng, nhưng tôi dự định sẽ sớm đăng một bài viết trên blog về nó.
ngoan cường

1

thử mã này ....

 @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
trên Android> 4.0 tôi sẽ nhận đượcjava.lang.IllegalStateException: A factory has already been set on this LayoutInflater
Tới Kra

1

Nếu bạn muốn đặt màu cho một mục menu riêng lẻ, tùy chỉnh chủ đề thanh công cụ không phải là giải pháp phù hợp. Để đạt được điều này, bạn có thể sử dụng android: actionLayout và chế độ xem hành động cho mục menu.

Đầu tiên tạo một tệp bố cục XML cho chế độ xem hành động. Trong ví dụ này, chúng tôi sử dụng một nút làm chế độ xem hành động:

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>

Trong đoạn mã trên, chúng tôi sử dụng android:textColor="?android:attr/colorAccent"để tùy chỉnh màu văn bản nút.

Sau đó, trong tệp bố cục XML của bạn cho menu, bao gồm app:actionLayout="@layout/menu_button"như hiển thị bên dưới:

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>

Ghi đè cuối cùng onCreateOptionsMenu()phương thức trong hoạt động của bạn:

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

... hoặc đoạn:

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

Để biết thêm chi tiết về chế độ xem hành động, hãy xem hướng dẫn dành cho nhà phát triển Android .


0

Đây là cách bạn có thể tô màu một mục menu cụ thể bằng màu sắc, hoạt động cho tất cả các cấp 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));
                                }
                            }
                        }
                    }
                });
            }
        }
    }
}

Bằng cách đó, bạn mất hiệu ứng bộ chọn nền, vì vậy đây là mã để áp dụng bộ chọn nền tùy chỉnh cho tất cả các mục menu con.

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

Đây cũng là chức năng của trình trợ giúp:

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

Để thay đổi màu văn bản, bạn chỉ có thể đặt chế độ xem tùy chỉnh cho MenuItem và sau đó bạn có thể xác định màu cho văn bản.

Mã mẫu: MenuItem.setActionView ()


Mặc dù đoạn mã này có thể giải quyết câu hỏi, bao gồm một lời giải thích thực sự giúp cải thiện chất lượng bài đăng của bạn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho độc giả trong tương lai và những người đó có thể không biết lý do cho đề xuất mã của bạn.
Mischa
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.