Android에서 메뉴 항목의 텍스트 색상을 변경하는 방법은 무엇입니까?


175

Android에서 메뉴 항목의 배경색을 변경할 수 있습니까?

누구든지 이것에 대한 해결책이 있으면 알려주십시오. 마지막 옵션은 분명히 사용자 정의하는 것이지만 사용자 정의하지 않고 텍스트 색상을 변경하는 방법이 있습니다.


이것에 대한 해결책을 알려주는 사람이 있습니까?
sunil

3
텍스트 색상, 텍스트보기의 배경색을 변경 하시겠습니까? 아니면 둘다? 둘 다 다릅니다. 질문의 틀을 다시 잡으십시오.
Abhinav Saxena

답변:


335

테마에서 하나의 간단한 라인 :)

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

19
참고 : 이것은 예를 들어서는 안되며 앱의 기본 테마 정의에 있어야합니다 actionBarStyle. actionBarStyle논리적으로 보이지만 에서 작동하지 않습니다 !
Colin M.

47
낮은 API 버전 사용을 지원하기 위해 <item name="actionMenuTextColor">@color/your_color</item>안드로이드 네임 스페이스를 사용하지 않는
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>

styles.xml에서 메뉴 항목이 아닌 목록 항목의 스타일을 변경하십시오.


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 2014

@bagusflyer 당신은 즉의 자식 인 스타일, 테마의 루트 스타일이를 추가해야 Theme.Holo하거나 Theme.Holo.Light.DarkActionBar또는 유사한.
Tash Pemhiwa 2016 년

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
이 사용 5+ 모두 4.4에서 나를 위해 일한 및 menu.findItem(R.id.menu_item_id);대신menu.getItem()
haagmm

1
[findItem (...)] 사용하여 저를 위해 일했습니다.
dazed

6
솔루션은 오버플로의 항목에 대해서만 작동합니다 .... showAsAction : "always"
Junaid

56

테마가있는 새 툴바를 사용하는 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> <inside items> </ 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
귀하의 답변은 MenuItem 텍스트를 굵게 설정하는 데 도움이되었습니다. (s.setSpan (new 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
이것은 마시멜로에서 작동하지 않습니다. 텍스트는 적용되지만 색상은 적용되지 않습니다.
Ollie C

마시멜로와 관련하여 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의 경우는 그 두 번째 내선 기능없이 작동
라즐로

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

안드로이드의 옵션 메뉴는 배경을 설정하거나 텍스트 모양을 변경하도록 사용자 정의 할 수 있습니다. 테마 및 스타일을 사용하여 메뉴의 배경 및 텍스트 색상을 변경할 수 없습니다. 안드로이드 소스 코드 (data \ res \ layout \ icon_menu_item_layout.xml)는 메뉴 레이아웃에 대해“com.android.internal.view.menu.IconMenuItem”View 클래스의 사용자 정의 항목을 사용합니다. 위 클래스에서 메뉴를 사용자 정의하기 위해 변경할 수 있습니다. 같은 결과를 얻으려면 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
Kra

이것은 처음으로 작동합니다. 두 번째로 메뉴를 열면 예외가 발생합니다.
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);
}

나에게 이것은 안드로이드 1.6, 2.03 및 4.03에서 작동합니다.


위의 작업을 수행하는 경우 Marcus Wolschon 솔루션을 사용하십시오. 훨씬 간단합니다.
chubbsondubs

xml 솔루션은 2.3.x에서 나에게 적합하지 않지만 이것은 매력처럼 작동합니다
-4.x

이 솔루션이 가장 효과적이었습니다. 호환성 라이브러리를 사용하여 장치에 적용되는 스타일을 가져 오려면 android.support.v7.internal.view.menu.ListMenuItemView도 캡처해야했습니다
Chiatar

이 수정 사항은 Google Maps v2에서 작동하지 않습니다.지도를 올바르게 렌더링하려면 super 메소드를 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);
}

하드 코딩 Color.BLACKsetMenuTextColor메소드에 대한 추가 매개 변수가 될 수 있습니다. 또한 나는이 메뉴 항목에만 사용했습니다 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

이것을 styles.xml에 추가하면 나를 위해 일했습니다.

<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에 대한 MainActivityAppCompat의 응용 프로그램에 대한 테마 의 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 라이브러리 의 소스 코드 (특히 .aar 패키지 의 res 폴더 사용)로 조사하고 싶었습니다 .

필자의 경우 Eclipse를 폭발 .aar 종속성 과 함께 사용했지만 . 기본 스타일을 변경하고 결과를 확인할 수있었습니다. Gradle 또는 Android Studio에서 직접 사용할 라이브러리를 폭발시키는 방법을 모릅니다 . 또 다른 조사 스레드가 필요합니다.

그래서 내 목적은 res / values ​​/ values.xml 파일에서 메뉴 텍스트에 사용 되는 색상을 찾는 것입니다 (색상 이 거의 확실했습니다).

  1. 해당 파일을 연 다음 모든 색상을 복제하고 기본 색상 아래에 배치하여 무시하고 할당 #f00 했습니다.
  2. 앱을 시작하십시오.
  3. 많은 요소가 빨간색 배경 또는 텍스트 색을 가졌습니다. 메뉴 항목도 있습니다. 그것이 내가 필요한 것입니다.
  4. 5-10 줄의 블록으로 추가 된 색상을 제거하면 secondary_text_default_material_light색상 항목으로 끝났습니다 .
  5. res 폴더 내의 파일에서 (또는 res / colors 내에서 더 나은) 이름을 검색 하면 color / abc_secondary_text_material_light.xml 파일 에서 한 번만 발견되었습니다 (이 작업에는 Sublime Text를 사용하므로 필요한 것을 쉽게 찾을 수 있습니다).
  6. 받는 백업 values.xml 8 개 용도가에 대한 발견@color/abc_secondary_text_material_light .
  7. 그것은이었다 때문에 4 2 개 테마에 남아 테마 : Base.ThemeOverlay.AppCompat.LightPlatform.AppCompat.Light.
  8. 첫 번째 주제는 두 번째의 자식이었다 그래서 색상 자원 만이 특성이 있었다 : android:textColorSecondaryandroid:textColorTertiary에서 Base.ThemeOverlay.AppCompat.Light.
  9. values.xml 에서 직접 값을 변경하고 앱을 실행하면 최종 올바른 속성이 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에서 코드를 복사하고 동작에 맞게 사용자 정의하십시오. Activity에서 사용하는 기본 메뉴 구현은 더 이상 적용되지 않습니다.

더 많은 힌트를 보려면 이슈 4441 : 사용자 정의 옵션 메뉴 테마 를 참조하십시오.


다시 말하지만 ... Sephy의 솔루션은 TextAppearance 메뉴 항목에서 작동하지만, 내가 한 것은 themes.xml을 통해 기본값을 무시하는 것입니다. 또한 위의 # 2 또는 # 3은 super # onCreateOptionsMenu / super # onPrepareOptionsMenu를 통한 호출은 Activity # onCreateOptionsMenu ()에 대한 javadoc에 표시된대로 시스템 메뉴 항목을 배치하도록 설계되었습니다. 앱에 중요하지 않을 수도 있습니다.
Tenacious

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
안드로이드> 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.