Zmień kolor paska stanu za pomocą AppCompat ActionBarActivity


145

W jednym z moich działań zmieniłem kolor paska narzędzi za pomocą Palette. Ale na 5,0 urządzeń wykorzystujących ActionBarActivityten status barkolor to kolor My colorPrimaryDarkw mojej działalności tematu więc mam 2 bardzo różne kolory i to nie wygląda dobrze.

Zdaję sobie sprawę, że w 5.0 można używać, Window.setStatusBarColor()ale ActionBarActivitytego nie ma.

więc moje pytanie dotyczy wersji 5.0, w jaki sposób mogę zmienić kolor paska stanu za pomocą ActionBarActivity?


Czy próbowałeś użyć SystemBarTint lib? github.com/jgilfelt/SystemBarTint
Nikola Despotoski

Odpowiedzi:


419

Nie jestem pewien, czy rozumiem problem.

Chcesz programowo zmienić kolor paska stanu (i pod warunkiem, że urządzenie ma Androida 5.0), możesz użyć Window.setStatusBarColor(). Nie powinno mieć znaczenia, czy działanie pochodzi z, Activityczy ActionBarActivity.

Po prostu spróbuj:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    Window window = getWindow();
    window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
    window.setStatusBarColor(Color.BLUE);
}

Właśnie to przetestowałem ActionBarActivityi działa dobrze.


Uwaga: Ustawienie FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDSflagi programowo nie jest konieczne, jeśli values-v21plik stylów już ją ustawił, poprzez:

    <item name="android:windowDrawsSystemBarBackgrounds">true</item>

1
ah ok, nie getWindow()
używałem

powodowałoby to awarię, gdy kod LOLLIPOP nie został znaleziony w starych androidach. najlepiej używać> = 21
code511788465541441

12
@ code578841441 Właściwie to nie powinno się zdarzyć. Stałe są wstawiane podczas kompilacji.
matiash

4
@ code578841441: To dlatego, że kompilujesz ze starszym SDK. Zawsze powinieneś dążyć do kompilacji z najnowszym Android SDK, nawet jeśli masz starsze ograniczenia wersji API (tj. minSdkVersionI / lub targetSdkVersionatrybuty <uses-sdk ...>elementu).
dbm

3
Musiałem również wywołać getWindow (). AddFlags (WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); aby to działało
Philipp E.

61

Istnieje wiele sposobów zmiany koloru paska stanu.

1) Za pomocą pliku styles.xml. Możesz użyć atrybutu android: statusBarColor, aby zrobić to w łatwy, ale statyczny sposób.

Uwaga: tego atrybutu można również używać z motywem Materiał.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="AppTheme" parent="AppTheme.Base">
        <item name="android:statusBarColor">@android:color/transparent</item>
    </style>
</resources>

2) Można to zrobić dynamicznie za pomocą metody setStatusBarColor (int) w klasie Window. Pamiętaj jednak, że ta metoda jest dostępna tylko dla API 21 lub nowszego. Więc pamiętaj, aby to sprawdzić, w przeciwnym razie Twoja aplikacja na pewno ulegnie awarii na niższych urządzeniach.

Oto działający przykład tej metody.

if (Build.VERSION.SDK_INT >= 21) {
            Window window = getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.setStatusBarColor(getResources().getColor(R.color.primaryDark));
}

gdzie primaryDark to 700 tint koloru podstawowego, którego używam w mojej aplikacji. Możesz zdefiniować ten kolor w pliku colors.xml.

Spróbuj i daj mi znać, jeśli masz jakieś pytania. Mam nadzieję, że to pomoże.


wygląda jak window.clearFlags (WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); nie jest potrzebny - ale ten działał dla mnie
bkurzius

Jakieś pomysły, dlaczego wersja programistyczna miałaby działać, a wersja stylu nie?
Andrew

W moim przypadku styl działania miał ustawiony flah translucent_status, więc bez polecenia window.clearFlags nie działało. Więc dziękuję za to!
BMacedo

Oh wow! To powinna zostać zaakceptowana odpowiedź, dodaj clearFlagsnapraw mój problem
fanjavaid

9

Nie sądzę, aby kolor paska stanu został jeszcze zaimplementowany w AppCompat. Oto atrybuty, które są dostępne:

    <!-- ============= -->
    <!-- Color palette -->
    <!-- ============= -->

    <!-- The primary branding color for the app. By default, this is the color applied to the
         action bar background. -->
    <attr name="colorPrimary" format="color" />

    <!-- Dark variant of the primary branding color. By default, this is the color applied to
         the status bar (via statusBarColor) and navigation bar (via navigationBarColor). -->
    <attr name="colorPrimaryDark" format="color" />

    <!-- Bright complement to the primary branding color. By default, this is the color applied
         to framework controls (via colorControlActivated). -->
    <attr name="colorAccent" format="color" />

    <!-- The color applied to framework controls in their normal state. -->
    <attr name="colorControlNormal" format="color" />

    <!-- The color applied to framework controls in their activated (ex. checked) state. -->
    <attr name="colorControlActivated" format="color" />

    <!-- The color applied to framework control highlights (ex. ripples, list selectors). -->
    <attr name="colorControlHighlight" format="color" />

    <!-- The color applied to framework buttons in their normal state. -->
    <attr name="colorButtonNormal" format="color" />

    <!-- The color applied to framework switch thumbs in their normal state. -->
    <attr name="colorSwitchThumbNormal" format="color" />

(Z \ sdk \ extras \ android \ support \ v7 \ appcompat \ res \ values ​​\ attrs.xml )


1
Możliwe, że nigdy nie zostanie zaimplementowany w AppCompat, jeśli starsze wersje systemu operacyjnego nie zapewniają możliwości modyfikowania paska stanu.
TheIT

2
<attr name = "colorPrimaryDark" format = "color" /> <! - Ciemny wariant podstawowego koloru marki. Domyślnie jest to kolor zastosowany do paska stanu (przez statusBarColor) i paska nawigacji (przez navigationBarColor). ->
Soheil Setayeshi

3

Spróbuj tego, użyłem tego i działa bardzo dobrze z wersją 21.

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light">
    <item name="colorPrimaryDark">@color/blue</item>
</style>

1

Dzięki za powyższe odpowiedzi, z pomocą tych, po pewnych badaniach i rozwoju dla aplikacji xamarin.android MVVMCross, poniżej działało

Flaga określona dla działania w metodzie OnCreate

protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        this.Window.AddFlags(WindowManagerFlags.DrawsSystemBarBackgrounds);
    }

Dla każdego MvxActivity, motyw jest wymieniony poniżej

 [Activity(
    LaunchMode = LaunchMode.SingleTop,
    ScreenOrientation = ScreenOrientation.Portrait,
    Theme = "@style/Theme.Splash",
    Name = "MyView"
    )]

Mój plik SplashStyle.xml wygląda jak poniżej

<?xml version="1.0" encoding="utf-8"?>
<resources> 
    <style name="Theme.Splash" parent="Theme.AppCompat.Light.NoActionBar">
          <item name="android:statusBarColor">@color/app_red</item>
          <item name="android:colorPrimaryDark">@color/app_red</item>
    </style>
 </resources>

I mam odniesienie do V7 appcompact.


1

[Wersja Kotlin] Stworzyłem to rozszerzenie, które sprawdza również, czy żądany kolor ma wystarczający kontrast, aby ukryć interfejs systemu, taki jak ikona stanu baterii, zegar itp., Więc zgodnie z tym ustawiamy interfejs systemu na biały lub czarny.

fun Activity.coloredStatusBarMode(@ColorInt color: Int = Color.WHITE, lightSystemUI: Boolean? = null) {
    var flags: Int = window.decorView.systemUiVisibility // get current flags
    var systemLightUIFlag = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
    var setSystemUILight = lightSystemUI

    if (setSystemUILight == null) {
        // Automatically check if the desired status bar is dark or light
        setSystemUILight = ColorUtils.calculateLuminance(color) < 0.5
    }

    flags = if (setSystemUILight) {
        // Set System UI Light (Battery Status Icon, Clock, etc)
        removeFlag(flags, systemLightUIFlag)
    } else {
        // Set System UI Dark (Battery Status Icon, Clock, etc)
        addFlag(flags, systemLightUIFlag)
    }

    window.decorView.systemUiVisibility = flags
    window.statusBarColor = color
}

private fun containsFlag(flags: Int, flagToCheck: Int) = (flags and flagToCheck) != 0

private fun addFlag(flags: Int, flagToAdd: Int): Int {
    return if (!containsFlag(flags, flagToAdd)) {
        flags or flagToAdd
    } else {
        flags
    }
}

private fun removeFlag(flags: Int, flagToRemove: Int): Int {
    return if (containsFlag(flags, flagToRemove)) {
        flags and flagToRemove.inv()
    } else {
        flags
    }
}

0

Stosowanie

    <item name="android:statusBarColor">@color/color_primary_dark</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>

in Theme.AppCompat.Light.DarkActionBarnie zadziałało dla mnie. Na czym polega sztuczka, dając colorPrimaryDarkjak zwykle razem z android:colorPrimarystyles.xml

<item name="android:colorAccent">@color/color_primary</item>
<item name="android:colorPrimary">@color/color_primary</item>
<item name="android:colorPrimaryDark">@color/color_primary_dark</item>

i ustawienie

if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
                {
                    Window window = this.Window;
                    Window.AddFlags(WindowManagerFlags.DrawsSystemBarBackgrounds);
                }

nie musiał ustawiać koloru paska stanu w kodzie.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.