Как изменить цвет стрелки назад в новой теме материала?

193

Я обновил свой SDK до API 21, и теперь значок возврата / вверх - черная стрелка, указывающая влево.

Черная стрелка назад

Я хотел бы, чтобы это было серым. Как я могу это сделать?

Например, в магазине Play Store стрелка белого цвета.

Я сделал это, чтобы установить некоторые стили. Я использовал @drawable/abc_ic_ab_back_mtrl_am_alphaдля homeAsUpIndicator. Этот чертеж является прозрачным (только альфа), но стрелка отображается черным цветом. Интересно, смогу ли я установить цвет, как я делаю в DrawerArrowStyle. Или, если единственным решением является создание моего @drawable/grey_arrowи использовать его для homeAsUpIndicator.

<!-- Base application theme -->
<style name="AppTheme" parent="Theme.AppCompat.Light">

    <item name="android:actionBarStyle" tools:ignore="NewApi">@style/MyActionBar</item>
    <item name="actionBarStyle">@style/MyActionBar</item>

    <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>

    <item name="homeAsUpIndicator">@drawable/abc_ic_ab_back_mtrl_am_alpha</item>
    <item name="android:homeAsUpIndicator" tools:ignore="NewApi">@drawable/abc_ic_ab_back_mtrl_am_alpha</item>
</style>

<!-- ActionBar style -->
<style name="MyActionBar" parent="@style/Widget.AppCompat.Light.ActionBar.Solid">

    <item name="android:background">@color/actionbar_background</item>
    <!-- Support library compatibility -->
    <item name="background">@color/actionbar_background</item>
</style>

<!-- Style for the navigation drawer icon -->
<style name="DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
    <item name="spinBars">true</item>
    <item name="color">@color/actionbar_text</item>
</style>

Мое решение до сих пор заключалось в том @drawable/abc_ic_ab_back_mtrl_am_alpha, чтобы взять то , что кажется белым, и нарисовать его в желаемом цвете с помощью фоторедактора. Это работает, хотя я бы предпочел использовать @color/actionbar_textкак в DrawerArrowStyle.

Ферран Майлинч
источник
Ни один из ответов на основе XML пока не решил эту проблему для меня, но я успешно использовал ваш код homeAsUpIndicator/, @drawable/abc_ic_ab_back_mtrl_am_alphaчтобы сделать стрелку назад белым. Я предпочитаю это, чем взломать Java.
запрет геоинженерии
Старый, но все же. Используете ли вы (были) ActionBar или новую панель инструментов?
f470071
По умолчанию предполагается, что он будет немного серым, используя android: theme = "@ style / Widget.AppCompat.Light.ActionBar" внутри тега XML панели инструментов. Его цвет # 737373
Android-разработчик

Ответы:

354

Вы можете достичь этого с помощью кода. Получите стрелку «Назад», измените ее цвет с помощью фильтра и установите ее в качестве кнопки «Назад».

final Drawable upArrow = getResources().getDrawable(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
upArrow.setColorFilter(getResources().getColor(R.color.grey), PorterDuff.Mode.SRC_ATOP);
getSupportActionBar().setHomeAsUpIndicator(upArrow);

Редакция 1:

Начиная с API 23 (Marshmallow) изменяемый ресурс abc_ic_ab_back_mtrl_am_alphaизменяется на abc_ic_ab_back_material.

РЕДАКТИРОВАТЬ:

Вы можете использовать этот код для достижения желаемых результатов:

toolbar.getNavigationIcon().setColorFilter(getResources().getColor(R.color.blue_gray_15), PorterDuff.Mode.SRC_ATOP);
Карлес
источник
4
Это единственное, что сработало для меня, не меняя оттенок всех остальных виджетов с помощью colorControlNormal
Joris
4
проблема с этим решением состоит в том, что он рисует все остальные стрелки назад, если вы хотите изменить только одну, а оставшуюся белую
dabluck
24
Оно работает. Обратите внимание, что вы должны использовать, ContextCompat.getDrawable(this, R.drawable.abc_ic_ab_back_mtrl_am_alpha)потому что getResources.getDrawable(int)устарела
mrroboaat
3
Другим возможным решением было бы получить этот ресурс самостоятельно и поместить его в свои папки для
рисования
12
Обратите внимание, что abc_ic_ab_back_mtrl_am_alpha изменено на abc_ic_ab_back_material в библиотеке поддержки 23.2.0
Jon
206

Глядя на Toolbarи TintManagerисточник, drawable/abc_ic_ab_back_mtrl_am_alphaокрашена со значением атрибута стиля colorControlNormal.

Я попытался установить это в своем проекте (с <item name="colorControlNormal">@color/my_awesome_color</item>моей темой), но он все еще черный для меня.

Обновление :

Нашел это. Вы должны установить actionBarThemeатрибут ( не actionBarStyle ) с помощью colorControlNormal.

Например:

<style name="MyTheme" parent="Theme.AppCompat.Light">        
    <item name="actionBarTheme">@style/MyApp.ActionBarTheme</item>
    <item name="actionBarStyle">@style/MyApp.ActionBar</item>
    <!-- color for widget theming, eg EditText. Doesn't effect ActionBar. -->
    <item name="colorControlNormal">@color/my_awesome_color</item>
    <!-- The animated arrow style -->
    <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
</style>

<style name="MyApp.ActionBarTheme" parent="@style/ThemeOverlay.AppCompat.ActionBar">       
    <!-- THIS is where you can color the arrow! -->
    <item name="colorControlNormal">@color/my_awesome_color</item>
</style>

<style name="MyApp.ActionBarStyle" parent="@style/Widget.AppCompat.Light.ActionBar">
    <item name="elevation">0dp</item>      
    <!-- style for actionBar title -->  
    <item name="titleTextStyle">@style/ActionBarTitleText</item>
    <!-- style for actionBar subtitle -->  
    <item name="subtitleTextStyle">@style/ActionBarSubtitleText</item>

    <!-- 
    the actionBarTheme doesn't use the colorControlNormal attribute
    <item name="colorControlNormal">@color/my_awesome_color</item>
     -->
</style>
rockgecko
источник
4
Это должен быть принятый ответ. Спасибо тебе за это. Вопрос, я не могу найти стиль для раскрашивания стрелки, отображаемой при расширении SearchView. Любая подсказка? Это очевидно не затронуто этим ответом.
Даниэль Очоа
6
Мне нужно также добавить <item name = "android: colorControlNormal"> ... </ item> с префиксом android:
Серафима
7
К сожалению, это API уровня 21, и если вы хотите что-то поддержать ниже, он не будет работать.
gphilip
10
Если ваша родительская тема происходит от одной из тем «NoActionBar», то путь к colorControlNormalкорневой теме, а не к, actionBarTheme- это путь.
Джейсон Робинсон
3
Мне потребовалось всего 2 часа поиска и неудачи и поиска снова, чтобы наконец добраться до этого. Иногда стиль «система» в Android сводит меня с ума! Этот метод особенно важно использовать, когда у вас есть одно действие, которое не использует тот же стиль, что и другие.
Брон Дэвис
119

Перепробовал все предложения выше. Единственный способ, которым мне удалось изменить цвет значка навигации по умолчанию - кнопка со стрелкой «Назад» на моей панели инструментов - это установить colorControlNormal в базовой теме следующим образом. Вероятно, из-за того, что родитель использует Theme.AppCompat.Light.NoActionBar

<style name="BaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
  <item name="colorControlNormal">@color/white</item> 
  //the rest of your codes...
</style>
Гарри Аунг
источник
6
style.xml
Самый простой
3
помните, что colorControlNormal требует API 21
Аднан Али
3
@AdnanAli, если вы используете AppCompat, он будет работать и в <API 21. Очевидно, что AppCompat в настоящее время используется здесь , потому что colorControlNormalэто не с префиксом android:.
Вики Чиджвани
3
Но это также меняет оттенок всех других виджетов ... никак не повлиять на другие виджеты, такие как флажки и переключатели?
Брюс
2
Но это также меняет цвет других элементов управления, таких как переключатели и строка под редактированием текста.
Дака
66

Необходимо добавить один атрибут в тему панели инструментов -

<style name="toolbar_theme" parent="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
    <item name="colorControlNormal">@color/arrow_color</item>
</style>

Примените эту toolbar_theme к вашей панели инструментов.

ИЛИ

Вы можете напрямую обратиться к своей теме -

<style name="CustomTheme" parent="Theme.AppCompat.Light.NoActionBar">
  <item name="colorControlNormal">@color/arrow_color</item> 
  //your code ....
</style>
Нео
источник
5
Попытка принять принятый ответ (возможно, самое популярное решение, найденное в сети) не работает для меня, но это работает :), так безумно, когда программируешь с Android.
Кинг Кинг
4
Самый простой ответ. Это работает без изменения других тем управления. Все, что вам нужно, это установить собственную тему панели инструментов на вашу панель инструментов. :)
SimplyProgrammer
1
О боли, которые вы должны пройти, чтобы изменить цвет только одного значка .. Первый работает для меня. Второй работает для пользовательских панелей инструментов (и других вещей, очевидно). Спустя 3 года огромное спасибо Нео.
Аба
45

Просто добавь

<item name="colorControlNormal">@color/white</item> 

к вашей текущей теме приложения.

С Брюс
источник
2
Это также меняет цвет android.support.v7.widget.AppCompatCheckBox
Udi
34

если использовать Toolbar, вы можете попробовать это

Drawable drawable = toolbar.getNavigationIcon();
drawable.setColorFilter(ContextCompat.getColor(appCompatActivity, colorId), PorterDuff.Mode.SRC_ATOP);
longbaobao
источник
Это должен быть принятый ответ, imho - он нацелен только на стрелку, получает стрелку для установки с использованием самых простых средств и совместим также с API 21
Antek
Если вы ищете более нестандартное решение (разные цвета для заголовков и значков меню в моем случае), то это то решение, которое вам нужно
TheJudge
3
Обратите внимание, что вам может потребоваться вызвать это перед попыткой вызова getNavigationIcon (): getSupportActionBar (). SetDisplayHomeAsUpEnabled (true);
rrbrambley
Лучший ответ! Спасибо.
Шарифуль Ислам
32

Как сказано в большинстве предыдущих комментариев, решение состоит в том, чтобы добавить

<item name="colorControlNormal">@color/white</item> в тему вашего приложения. Но убедитесь, что у вас нет другой темы, определенной в элементе панели инструментов в макете.

     <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:elevation="4dp"
            android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
manuelvsc
источник
3
Гениально ... Я попробовал все варианты ответов, чтобы добавить его в тему, но это не сработало ... Как вы упомянули, у меня на панели инструментов было свойство android: theme = "@ style / ThemeOverlay.AppCompat.ActionBar". Как только я удалил его, он начал работать.
Рахул Хоге
10

Ответ Карлеса является правильным, но некоторые методы, такие как getDrawable (), getColor (), устарели во время написания этого ответа . Таким образом, обновленный ответ будет

Drawable upArrow = ContextCompat.getDrawable(context, R.drawable.abc_ic_ab_back_mtrl_am_alpha);
upArrow.setColorFilter(ContextCompat.getColor(context, R.color.white), PorterDuff.Mode.SRC_ATOP);
getSupportActionBar().setHomeAsUpIndicator(upArrow);

Следуя другим запросам stackoverflow, я обнаружил, что вызов ContextCompat.getDrawable () похож на

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    return resources.getDrawable(id, context.getTheme());
} else {
    return resources.getDrawable(id);
}

И ContextCompat.getColor () похож на

public static final int getColor(Context context, int id) {
    final int version = Build.VERSION.SDK_INT;
    if (version >= 23) {
        return ContextCompatApi23.getColor(context, id);
    } else {
        return context.getResources().getColor(id);
    }
}

Ссылка 1: ContextCompat.getDrawable ()

Ссылка 2: ContextCompat.getColor ()

capt.swag
источник
Так должно быть abc_ic_ab_back_material, а не abc_ic_ab_back_mtrl_am_alpha.
Нарендра Сингх
7

Я нашел решение, которое работает до Lollipop. Установите «colorControlNormal» в «actionBarWidgetTheme», чтобы изменить цвет homeAsUpIndicator. Измените ответ Rockgecko сверху, чтобы он выглядел так:

<style name="MyTheme" parent="Theme.AppCompat.Light">        
    <item name="actionBarTheme">@style/MyApp.ActionBarTheme</item>
    <item name="actionBarStyle">@style/MyApp.ActionBar</item>
    <!-- color for widget theming, eg EditText. Doesn't effect ActionBar. -->
    <item name="colorControlNormal">@color/my_awesome_color</item>
    <!-- The animated arrow style -->
    <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
    <!-- The style for the widgets on the ActionBar. -->
    <item name="actionBarWidgetTheme">@style/WidgetStyle</item>
</style>

<style name="WidgetStyle" parent="style/ThemeOverlay.AppCompat.Light">
    <item name="colorControlNormal">@color/my_awesome_color</item>
</style>
GFred
источник
7

На compileSdkVersoin 25 вы можете сделать это:

styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light">
     <item name="android:textColorSecondary">@color/your_color</item>
</style>
nuttynibbles
источник
6

Используйте метод ниже:

private Drawable getColoredArrow() {
    Drawable arrowDrawable = getResources().getDrawable(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
    Drawable wrapped = DrawableCompat.wrap(arrowDrawable);

    if (arrowDrawable != null && wrapped != null) {
        // This should avoid tinting all the arrows
        arrowDrawable.mutate();
        DrawableCompat.setTint(wrapped, Color.GRAY);
    }

    return wrapped;
}

Теперь вы можете установить рисование с помощью:

getSupportActionBar().setHomeAsUpIndicator(getColoredArrow());
Jumpa
источник
6

введите описание изображения здесь

Изменить цвет значка меню навигации

Окончательное преобразование цвета иконки меню

В style.xml:

<style name="MyMaterialTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="windowNoTitle">true</item>
    <item name="windowActionBar">false</item>
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
    <item name="android:textColor">@color/colorAccent</item>


</style>

<style name="DrawerArrowStyle" parent="@style/Widget.AppCompat.DrawerArrowToggle">
    <item name="spinBars">true</item>
    <item name="color">@color/colorPrimaryDark</item>
</style>







In Mainfests.xml :

<activity android:name=".MainActivity"
        android:theme="@style/MyMaterialTheme.Base"></activity>
Сумит Саксена
источник
5

Другое решение, которое может работать для вас, состоит в том, чтобы не объявлять вашу панель инструментов как панель действий приложения (с помощью setActionBarили setSupportActionBar) и устанавливать значок возврата в вашем onActivityCreated, используя код, упомянутый в другом ответе на этой странице.

final Drawable upArrow = getResources().getDrawable(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
upArrow.setColorFilter(getResources().getColor(R.color.grey), PorterDuff.Mode.SRC_ATOP);
toolbar.setNavigationIcon(upArrow);

Теперь вы не получите onOptionItemSelectedобратный вызов при нажатии кнопки возврата. Тем не менее, вы можете зарегистрироваться для этого, используя setNavigationOnClickListener. Вот что я делаю:

toolbar.setNavigationOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        getActivity().onBackPressed(); //or whatever you used to do on your onOptionItemSelected's android.R.id.home callback
    }
});

Я не уверен, будет ли это работать, если вы работаете с пунктами меню.

Vinay W
источник
3

Мы столкнулись с той же проблемой, и все, что мы хотели, это установить

Приложение: collapseIcon

атрибут на панели инструментов в конце концов, который мы не нашли, так как он не очень хорошо задокументирован :)

<android.support.v7.widget.Toolbar
         android:id="@+id/toolbar"
         android:layout_width="match_parent"
         android:layout_height="@dimen/toolbarHeight"
         app:collapseIcon="@drawable/collapseBackIcon" />
Джулиан Хорст
источник
3

попробуй это

public void enableActionBarHomeButton(AppCompatActivity appCompatActivity, int colorId){

    final Drawable upArrow = ContextCompat.getDrawable(appCompatActivity, R.drawable.abc_ic_ab_back_material);
    upArrow.setColorFilter(ContextCompat.getColor(appCompatActivity, colorId), PorterDuff.Mode.SRC_ATOP);

    android.support.v7.app.ActionBar mActionBar = appCompatActivity.getSupportActionBar();
    mActionBar.setHomeAsUpIndicator(upArrow);
    mActionBar.setHomeButtonEnabled(true);
    mActionBar.setDisplayHomeAsUpEnabled(true);
}

вызов функции:

enableActionBarHomeButton(this, R.color.white);
Сиддарт Кантед
источник
Установка параметра отображения {@link #DISPLAY_HOME_AS_UP} автоматически активирует кнопку «Домой».
П. Савров
2

Вот что сработало для меня:

Добавьте следующие атрибуты к вашей теме.

Чтобы изменить панель инструментов / панель действий назад стрелка над API 21

<item name="android:homeAsUpIndicator">@drawable/your_drawable_icon</item>

Чтобы изменить панель инструментов / панель действий назад стрелка ниже API 21

<item name="homeAsUpIndicator">@drawable/your_drawable_icon</item>

Для изменения режима действия стрелка назад

<item name="actionModeCloseDrawable">@drawable/your_drawable_icon</item>

Чтобы удалить тень панели инструментов / панели действий

<item name="android:elevation" tools:targetApi="lollipop">0dp</item>
<item name="elevation">0dp</item>
<!--backward compatibility-->
<item name="android:windowContentOverlay">@null</item>

Чтобы изменить рисование переполнения панели действий

<!--under theme-->
<item name="actionOverflowButtonStyle">@style/MenuOverflowStyle</item>

<style name="MenuOverflowStyle" parent="Widget.AppCompat.ActionButton.Overflow">
<item name="srcCompat">@drawable/ic_menu_overflow</item>

Примечание: вместо «android: src» используется «srcCompat» из-за поддержки векторного рисования для API ниже 21

Sadashiv
источник
2

Решение очень простое

Просто поместите следующую строку в свой стиль, названный AppTheme

<item name="colorControlNormal">@color/white</item>

Теперь весь ваш xml-код будет выглядеть так, как показано ниже (стиль по умолчанию).

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

        <item name="colorPrimary">#0F0F0F</item>
        <item name="android:statusBarColor">#EEEEF0</item>
        <item name="android:windowLightStatusBar">true</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:windowActivityTransitions">true</item>

        <item name="colorControlNormal">@color/white</item>
</style>
Suyog
источник
1

Я просто изменил тему панели инструментов на @ style / ThemeOverlay.AppCompat.Light

и стрелка стала темно-серой

            <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:gravity="center"
            app:layout_collapseMode="pin"
            app:theme="@style/ThemeOverlay.AppCompat.Light">
Бадр
источник
1

Вот как я это сделал в Материальных Компонентах:

<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
    <item name="drawerArrowStyle">@style/AppTheme.DrawerArrowToggle</item>
</style>

<style name="AppTheme.DrawerArrowToggle" parent="Widget.AppCompat.DrawerArrowToggle">
    <item name="color">@android:color/white</item>
</style>
Сэм
источник
Приятель, ты спас мой день. Я провел весь день только на этом. Я хотел бы дать вам больше голосов.
Давал Патель
0

Вы можете изменить цвет значка навигации программно следующим образом:

mToolbar.setNavigationIcon(getColoredArrow()); 

private Drawable getColoredArrow() {
        Drawable arrowDrawable = getResources().getDrawable(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
        Drawable wrapped = DrawableCompat.wrap(arrowDrawable);

        if (arrowDrawable != null && wrapped != null) {
            // This should avoid tinting all the arrows
            arrowDrawable.mutate();
                DrawableCompat.setTintList(wrapped, ColorStateList.valueOf(this.getResources().getColor(R.color.your_color)));
            }
        }

        return wrapped;
}
PKS
источник
-1

Просто удалите android:homeAsUpIndicatorи homeAsUpIndicatorиз вашей темы и все будет хорошо. colorАтрибут в вашем DrawerArrowStyleстиле должно быть достаточно.

Флавио Фариа
источник
Я уже попробовал это, и стрелка черная. Обратите внимание, что эта стрелка - не та стрелка, которую вы видите, когда открываете ящик (эта стрелка ДЕЙСТВИТЕЛЬНО зависит от colorатрибута). Стрелка ящика немного больше.
Ферран Мэйлинч
1
Так что, похоже, вам придется предоставить свой собственный ресурс для рисования. Вы можете создать его с помощью этого инструмента: shreyasachar.github.io/AndroidAssetStudio
Flávio Faria
-4

Если нет лучшего решения ...

Я взял @drawable/abc_ic_ab_back_mtrl_am_alphaизображения, которые кажутся белыми, и покрасил их в нужный мне цвет с помощью фоторедактора.

Ферран Майлинч
источник