Jak zmienić kolor strzałki wstecz w nowym temacie materiału?

193

Zaktualizowałem mój SDK do API 21, a teraz ikona cofania / w górę jest czarną strzałką skierowaną w lewo.

Czarna strzałka wstecz

Chciałbym, żeby był szary. Jak mogę to zrobić?

Na przykład w Sklepie Play strzałka jest biała.

Zrobiłem to, aby ustawić niektóre style. Użyłem @drawable/abc_ic_ab_back_mtrl_am_alphadla homeAsUpIndicator. Ta rysunkowa jest przezroczysta (tylko alfa), ale strzałka jest wyświetlana na czarno. Zastanawiam się, czy mogę ustawić kolor tak, jak robię to w DrawerArrowStyle. Lub jeśli jedynym rozwiązaniem jest utworzenie mojego @drawable/grey_arrowi użycie go 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>

Moje dotychczasowe rozwiązanie polegało na pobraniu @drawable/abc_ic_ab_back_mtrl_am_alpha, który wydaje się być biały, i pomalowaniu go na żądany kolor za pomocą edytora zdjęć. Działa, chociaż wolałbym używać @color/actionbar_textjak w DrawerArrowStyle.

Ferran Maylinch
źródło
Żadna z dotychczasowych odpowiedzi opartych na XML nie rozwiązała dla mnie tego problemu, ale z powodzeniem użyłem Twojego kodu homeAsUpIndicator/, @drawable/abc_ic_ab_back_mtrl_am_alphaaby biała strzałka wsteczna była biała. Wolę to niż włamanie się do Javy.
zakaz geoinżynierii
Stare, ale wciąż. Czy używasz ActionBar lub nowego paska narzędzi?
f470071,
Domyślny powinien być nieco szary, używając Androida: theme = "@ style / Widget.AppCompat.Light.ActionBar" wewnątrz tagu XML paska narzędzi. Jego kolor to # 737373
programista Androida

Odpowiedzi:

354

Możesz to osiągnąć za pomocą kodu. Uzyskaj rysowaną strzałkę wstecz, zmień jej kolor za pomocą filtra i ustaw ją jako przycisk cofania.

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

Wersja 1:

Począwszy od API 23 (Marshmallow) zasób do rysowania abc_ic_ab_back_mtrl_am_alphazmienia się na abc_ic_ab_back_material.

EDYTOWAĆ:

Możesz użyć tego kodu, aby osiągnąć pożądane wyniki:

toolbar.getNavigationIcon().setColorFilter(getResources().getColor(R.color.blue_gray_15), PorterDuff.Mode.SRC_ATOP);
Carles
źródło
4
To jedyna rzecz, która działała dla mnie bez zmiany odcienia wszystkich innych widżetów z colorControlNormal
Joris
4
Problem z tym rozwiązaniem polega na tym, że maluje on wszystkie pozostałe tylne strzałki, jeśli chcesz tylko zmienić jedną, a resztę pozostawić na biało
dabluck
24
To działa. Pamiętaj, że powinieneś używać, ContextCompat.getDrawable(this, R.drawable.abc_ic_ab_back_mtrl_am_alpha)ponieważ getResources.getDrawable(int)jest przestarzały
mrroboaat
3
Innym możliwym rozwiązaniem byłoby samodzielne zdobycie tego zasobu i umieszczenie go w folderach do rysowania :)
Mauker,
12
Zauważ, że abc_ic_ab_back_mtrl_am_alpha zmieniono na abc_ic_ab_back_material w bibliotece obsługi 23.2.0
Jon
206

Patrząc na Toolbari TintManagerźródło, drawable/abc_ic_ab_back_mtrl_am_alphajest zabarwione wartością atrybutu stylu colorControlNormal.

Próbowałem ustawić to w moim projekcie (z <item name="colorControlNormal">@color/my_awesome_color</item>moim motywem), ale nadal jest dla mnie czarne.

Aktualizacja :

Znaleziono to. Musisz ustawić actionBarThemeatrybut ( nie actionBarStyle ) za pomocą colorControlNormal.

Na przykład:

<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
źródło
4
To powinna być zaakceptowana odpowiedź. Dziękuję Ci za to. Pytanie, nie jestem w stanie znaleźć stylu do kolorowania strzałki wyświetlanej po rozwinięciu SearchView. Jakieś wskazówki? Ta odpowiedź najwyraźniej nie ma na to wpływu.
Daniel Ochoa
6
Muszę dodać również <item name = "android: colorControlNormal"> ... </ item> z Androidem: prefiks
Seraphim za
7
Niestety jest to interfejs API poziomu 21 i jeśli chcesz wesprzeć coś poniżej, nie będzie działać.
gphilip
10
Jeśli motyw nadrzędny wywodzi się z jednego z motywów „NoActionBar”, to ustawienie colorControlNormalmotywu głównego zamiast na drodze actionBarThemeto droga.
Jason Robinson
3
Zajęło mi to tylko 2 godziny poszukiwań i niepowodzeń i ponownych poszukiwań, aby w końcu do tego dojść. Czasami styl „system” w Androidzie doprowadza mnie do szału! Ta metoda jest szczególnie ważna w przypadku, gdy masz jedno działanie, które nie używa tego samego stylu, co inne.
Bron Davies
119

Wypróbowałem wszystkie sugestie powyżej. Jedynym sposobem, w jaki udało mi się zmienić kolor domyślnej ikony nawigacji Strzałka przycisku Wstecz na moim pasku narzędzi, jest ustawienie colorControlNormal w podstawowym temacie takim jak ten. Prawdopodobnie z powodu faktu, że rodzic używa Theme.AppCompat.Light.NoActionBar

<style name="BaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
  <item name="colorControlNormal">@color/white</item> 
  //the rest of your codes...
</style>
Harry Aung
źródło
6
Najprostsza odpowiedź ze wszystkich, zamiast majstrować przy innym kodzie, wystarczy dodać ten wiersz w swoimstyle.xml
Rohan Kandwal
3
pamiętaj, że colorControlNormal wymaga API 21
Adnan Ali
3
@AdnanAli, jeśli używasz AppCompat, będzie również działał na <API 21. Najwyraźniej jest tutaj używany AppCompat , ponieważ niecolorControlNormal ma przedrostka . android:
Vicky Chijwani,
3
Ale to zmienia również odcień wszystkich innych widżetów. W jakiś sposób nie wpływać na inne widżety, takie jak pole wyboru i przyciski opcji?
Bruce
2
Ale to także zmienia kolor innych kontrolek, takich jak przyciski opcji i linia pod edycją tekstu.
daka
66

Musisz dodać pojedynczy atrybut do motywu paska narzędzi -

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

Zastosuj ten toolbar_theme do paska narzędzi.

LUB

możesz bezpośrednio zastosować do swojego motywu -

<style name="CustomTheme" parent="Theme.AppCompat.Light.NoActionBar">
  <item name="colorControlNormal">@color/arrow_color</item> 
  //your code ....
</style>
Neo
źródło
5
Próbowanie zaakceptowanej odpowiedzi (być może najpopularniejszego rozwiązania znalezionego w sieci) nie działa dla mnie, ale to działa :) tak szalone, gdy programujesz na Androidzie.
King King
4
Najprostsza odpowiedź. Działa to bez zmiany innych motywów sterowania. Wystarczy ustawić niestandardowy motyw paska narzędzi na pasku narzędzi. :)
SimplyProgrammer
1
Och, bóle, przez które trzeba przejść, aby zmienić kolor tylko 1 ikony. Pierwsza działa dla mnie. Drugi działa dla niestandardowych pasków narzędzi (i innych rzeczy zbyt widocznie). 3 lata później, wielkie dzięki Neo.
Aba
45

Poprostu dodaj

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

do bieżącego motywu aplikacji.

S Bruce
źródło
2
To zmienia także kolor android.support.v7.widget.AppCompatCheckBox
Udi Oshi
34

jeśli używasz Toolbar, możesz spróbować tego

Drawable drawable = toolbar.getNavigationIcon();
drawable.setColorFilter(ContextCompat.getColor(appCompatActivity, colorId), PorterDuff.Mode.SRC_ATOP);
longbaobao
źródło
To powinna być zaakceptowana odpowiedź, imho - celuje tylko w strzałkę, ustawia strzałkę w najprostszy sposób i jest kompatybilny również poniżej API 21
Antek
Jeśli szukasz bardziej niestandardowego rozwiązania (różne kolory tytułów i ikon menu w moim przypadku), to jest to rozwiązanie, które chcesz
TheJudge
3
Zauważ, że może być konieczne wywołanie tego przed próbą wywołania getNavigationIcon (): getSupportActionBar (). SetDisplayHomeAsUpEnabled (true);
rrbrambley
Najlepsza odpowiedź! Dziękuję Ci.
ostry islam
32

Jak powiedziano w większości poprzednich komentarzy, rozwiązaniem jest dodanie

<item name="colorControlNormal">@color/white</item> do motywu aplikacji. Ale potwierdź, że nie masz innego motywu zdefiniowanego w elemencie paska narzędzi Toolbar w układzie.

     <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
źródło
3
Genialne ... Próbowałem wszystkich odpowiedzi, aby dodać go do motywu, ale to nie działało ... Jak wspomniałeś, miałem android: theme = "@ style / ThemeOverlay.AppCompat.ActionBar" na pasku narzędzi. Gdy go usunąłem, zaczął działać.
Rahul Hawge
10

Odpowiedź Carlesa jest poprawną odpowiedzią, ale kilka metod, takich jak getDrawable (), getColor (), stało się przestarzałe w momencie, gdy piszę tę odpowiedź . Tak więc zaktualizowana odpowiedź brzmi:

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

Po kilku innych zapytaniach dotyczących przepływu stosu odkryłem, że wywołanie ContextCompat.getDrawable () jest podobne do

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

A ContextCompat.getColor () jest podobny do

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

Link 1: ContextCompat.getDrawable ()

Link 2: ContextCompat.getColor ()

capt.swag
źródło
Powinno być abc_ic_ab_back_materialzamiast abc_ic_ab_back_mtrl_am_alpha.
Narendra Singh,
7

Znalazłem rozwiązanie, które działa przed Lollipop. Ustaw „colorControlNormal” w „actionBarWidgetTheme”, aby zmienić kolor homeAsUpIndicator. Modyfikowanie odpowiedzi rockgecko z góry, aby wyglądała następująco:

<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
źródło
7

W compileSdkVersoin 25 możesz to zrobić:

styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light">
     <item name="android:textColorSecondary">@color/your_color</item>
</style>
orzechy włoskie
źródło
6

Użyj poniższej metody:

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

Teraz możesz ustawić rysowanie za pomocą:

getSupportActionBar().setHomeAsUpIndicator(getColoredArrow());
Jumpa
źródło
6

wprowadź opis zdjęcia tutaj

Zmień kolor ikony nawigacji w menu

Kolor końcowej ikony menu konwersji

W 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>
Sumit Saxena
źródło
5

Innym rozwiązaniem, które może Ci się przydać, jest niezadeklarowanie paska narzędzi jako paska akcji aplikacji (przez setActionBarlub setSupportActionBar) i ustawienie ikony powrotu w swoim polu onActivityCreated za pomocą kodu wymienionego w innej odpowiedzi na tej stronie

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

Teraz nie otrzymasz połączenia onOptionItemSelectedzwrotnego po naciśnięciu przycisku Wstecz. Możesz jednak zarejestrować się za pomocą setNavigationOnClickListener. Tym się właśnie zajmuję:

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

Nie jestem pewien, czy to zadziała, jeśli będziesz pracować z elementami menu.

Vinay W.
źródło
3

Napotkaliśmy ten sam problem i wszystko, czego chcieliśmy, to ustawić

aplikacja: collapseIcon

atrybut na pasku narzędzi na końcu, którego nie znaleźliśmy, ponieważ nie jest zbyt dobrze udokumentowany :)

<android.support.v7.widget.Toolbar
         android:id="@+id/toolbar"
         android:layout_width="match_parent"
         android:layout_height="@dimen/toolbarHeight"
         app:collapseIcon="@drawable/collapseBackIcon" />
Julian Horst
źródło
3

Spróbuj tego

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

wywołanie funkcji:

enableActionBarHomeButton(this, R.color.white);
Siddarth Kanted
źródło
Ustawienie opcji wyświetlania {@link #DISPLAY_HOME_AS_UP} spowoduje automatyczne włączenie przycisku strony domowej.
P. Savrov
2

Oto, co zadziałało dla mnie:

Dodaj poniższe atrybuty do swojego motywu.

Aby zmienić pasek narzędzi / strzałkę wstecz na pasku narzędzi powyżej interfejsu 21

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

Aby zmienić pasek narzędzi / strzałkę wstecz paska narzędzi poniżej interfejsu 21

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

Aby zmienić tryb działania strzałkę wstecz

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

Aby usunąć cień paska narzędzi / działania

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

Aby zmienić przepełnienie paska akcji, można go pobrać

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

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

Uwaga: zamiast „android: src” użyto „srcCompat”, ponieważ obsługa rysunków wektorowych dla interfejsu API poniżej 21

Sadashiv
źródło
2

Rozwiązanie jest bardzo proste

Po prostu wstaw następującą linię do swojego stylu o nazwie AppTheme

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

Teraz cały kod xml będzie wyglądał jak pokazano poniżej (styl domyślny).

<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
źródło
1

Właśnie zmieniłem motyw paska narzędzi na @ style / ThemeOverlay.AppCompat.Light

i strzała stała się ciemnoszara

            <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">
Badr
źródło
1

Oto jak to zrobiłem w Material Components:

<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>
Sam
źródło
Kolego, uratowałeś mi dzień. Spędziłem cały dzień tylko na tym jednym. Chciałbym dać ci więcej głosów.
Dhaval Patel
0

Możesz zmienić kolor ikony nawigacji programowo w następujący sposób:

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;
}
szt
źródło
-1

Wystarczy wyjąć android:homeAsUpIndicatori homeAsUpIndicatorod tematu i będzie dobrze. colorAtrybut w swoim DrawerArrowStylestylu musi wystarczyć.

Flávio Faria
źródło
Próbowałem już tego, a strzałka jest czarna. Zwróć uwagę, że ta strzałka nie jest tą samą strzałką, którą widzisz po otwarciu szuflady (na tę strzałkę ma wpływ coloratrybut). Strzałka szuflady jest nieco większa.
Ferran Maylinch
1
Wygląda więc na to, że będziesz musiał zapewnić własne zasoby do wyciągania. Możesz go wygenerować za pomocą tego narzędzia: shreyasachar.github.io/AndroidAssetStudio
Flávio Faria
-4

Chyba że istnieje lepsze rozwiązanie ...

To, co zrobiłem, to zrobić @drawable/abc_ic_ab_back_mtrl_am_alphazdjęcia, które wydają się białe, i pomalować je na żądany kolor za pomocą edytora zdjęć.

Ferran Maylinch
źródło