Як змінити колір рядка стану в Android?


427

Перш за все це не дублікат, як у розділі Як змінити колір тла панелі стану андроїда

Як змінити колір рядка стану, який повинен бути таким же, як у панелі навігації.

Я хочу, щоб колір рядка стану був таким самим, як колір панелі навігації

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


2
це можливо тільки після kitkat @MarkBuikema
codercat

4
Як пропонує Нільс, існує ТЕМА АТРИБУТ з часу виклику v21 android:statusBarColor. Ви можете просто додати його values-v21/styles.xml.
Левіт

@MarkBuikema Як це навіть пов'язано з кореневим доступом!
steve moretz

Відповіді:


625

Android 5.0 Lollipop представив тему Material Design, яка автоматично забарвлює рядок стану на основі colorPrimaryDark значення теми.

Це підтримується на пристрої pre-lillipop завдяки бібліотеці support-v7-appcompat починаючи з версії 21. Blogpost про підтримку appcompat v21 від Chris Banes

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

Детальніше про тему "Матеріал" читайте на офіційному веб-сайті розробників Android


29
чомусь атрибут colorPrimaryDark не працює для мене. приміряв емулятор v21
девіантний

3
Це працює, ви повинні бачити зміни на емуляторі не в попередньому перегляді макета [він там не відображається]
Mightian

6
colorPrimaryDark не працює для мене ні на емуляторі API 18. Зі статті, пов’язаної з appcompat: "На старих платформах AppCompat імітує кольорову тематику, де це можливо. На даний момент це обмежується забарвленням панелі дій та деяких віджетів".
Адам Джонс

12
Як щодо зміни кольору шрифту в рядку стану? Документи про це нічого не говорять.
Скотт Біггс

Я намагався так само. він працює чудово на більшості всіх пристроїв, але у мене є samsung galaxy s4 під управлінням ОС 5.0.1, а в цьому рядку стану телефону колір - чорний. І як тільки я переходжу до іншої діяльності та знову повертаюся до попередньої діяльності, мій колір рядка стану змінюється на колір теми додатка. Будь-яка причина, чому це відбувається
Хітеш Камані

364

Оновлення:

Льодяник:

public abstract void setStatusBarColor (int color)

Додано в рівень 21

Android Lollipop приніс із собою можливість змінювати колір рядка статусу у вашому додатку для більш зануреного користувальницького досвіду та співзвучного Google Material Design Guidelines.

Ось як можна змінити колір рядка стану за допомогою нового window.setStatusBarColorметоду, введеного в API level 21.

Зміна кольору рядка стану також потребує встановлення двох додаткових прапорів у вікні; вам потрібно додати FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDSпрапор і очистити FLAG_TRANSLUCENT_STATUSпрапор.

Код роботи:

import android.view.Window;

...

Window window = activity.getWindow();

// clear FLAG_TRANSLUCENT_STATUS flag:
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

// add FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag to the window
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

// finally change the color
window.setStatusBarColor(ContextCompat.getColor(activity,R.color.my_statusbar_color));

Офіційна посилання розробника: setStatusBarColor (int)

Приклад: матеріал-дизайн-скрізь

Блог Кріса Бейнса - appcompat v21: дизайн матеріалів для пристроїв до Lollipop!

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

transitionNameДля перегляду фону буде android:status:background.


2
Будь-яке рішення для зворотної сумісності?
Адам Гурвіц

Як зазначається у відповіді Нільса: ви також можете налаштувати колір рядка стану за темою / стилем, встановивши android:statusBarColorу своєму values-v21/styles.xmlфайлі по androiddocs.com/training/material/theme.html так<item name="android:statusBarColor">@color/primary_color</item>
JL West

4
я можу змінити колір рядка стану на білий, але я не бачу піктограми сповіщень, як батарея, як я можу це вирішити?
MNFS

1
Ви не маєте поняття, скільки ви мені просто допомогли ..
Абхішек Дяні

222

Розмістіть це ваші значення-v21 / styles.xml, щоб увімкнути це на Lollipop:

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light">
        <item name="colorPrimary">@color/color_primary</item>
        <item name="colorPrimaryDark">@color/color_secondary</item>
        <item name="colorAccent">@color/color_accent</item>
        <item name="android:statusBarColor">@color/color_primary</item>
    </style>
</resources>

34
для цього потрібно min API 21
Роман

49
Це, мабуть, тому він запропонував ввести це у значення-v21 / styles.xml ;-) На сьогодні це найточніша відповідь !!
Левіт

Але це все ще прапори попередження !!?
Ніхал Шарма

яка функція для compat? смуга стану
blackHawk

ви можете додати targeApiатрибут, якщо хочете підтримувати єдиний файл стилю. Прочитайте мою відповідь для довідки stackoverflow.com/a/48565459/4291272
Faisal Shaikh

50

це дуже простий спосіб зробити це без будь-якої бібліотеки: якщо версія ОС не підтримується - під kitkat - так нічого не відбудеться. я роблю ці кроки:

  1. в моєму xml я додав вгору цей вид:
<View
        android:id="@+id/statusBarBackground"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

тоді я зробив цей метод:

 public void setStatusBarColor(View statusBar,int color){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
           Window w = getWindow();
           w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
           //status bar height
           int actionBarHeight = getActionBarHeight();
           int statusBarHeight = getStatusBarHeight();
           //action bar height
           statusBar.getLayoutParams().height = actionBarHeight + statusBarHeight;
           statusBar.setBackgroundColor(color);
     }
}

також потрібні ці обидва способи, щоб отримати висоту смуги бар та висоту смуги стану:

public int getActionBarHeight() {
    int actionBarHeight = 0;
    TypedValue tv = new TypedValue();
    if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
    {
       actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
    }
    return actionBarHeight;
}

public int getStatusBarHeight() {
    int result = 0;
    int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0) {
        result = getResources().getDimensionPixelSize(resourceId);
    }
    return result;
}

тоді єдине, що вам потрібно - це лінія для встановлення кольору рядка стану:

setStatusBarColor(findViewById(R.id.statusBarBackground),getResources().getColor(android.R.color.white));

1
куди я повинен помістити елемент перегляду? чи має бути вона над головною схемою?
Еміль Ренья Енрікес

Так. У вашому xml У верхній частині.
ітжар

Обережно: працюю лише для Android> = 19 API. У моєму випадку мені потрібна підтримка починаючи з 16
Антон Кізема

setStatusBarColor (findViewById (android.R.id.statusBarBackground), getResources (). getColor (android.R.color.white));
AndroidLad

34

Як @Niels сказав, що ви повинні розміщувати у значення-v21 / styles.xml:

<item name="android:statusBarColor">@color/black</item>

Але додайте, tools:targetApi="lollipop"якщо ви хочете одиничного styles.xml, наприклад:

<item name="android:statusBarColor" tools:targetApi="lollipop">@color/black</item>

3
Дякую за "targetApi". Мені не подобається, щоб моя тема була розбита по декількох файлах. :)
сплетіння

31

Ну, рішення Іжара було в порядку, але особисто я намагаюся уникати коду, який виглядає так:

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//Do what you need for this SDK
};

Також я не люблю копіювати код. У Вашій відповіді я повинен додати такий рядок коду у всіх видах діяльності:

setStatusBarColor(findViewById(R.id.statusBarBackground),getResources().getColor(android.R.color.white));

Отже, я взяв рішення Іжара і використав XML, щоб отримати той самий результат: Створіть макет для StatusBar status_bar.xml

<View xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="@dimen/statusBarHeight"
     android:background="@color/primaryColorDark"
     android:elevation="@dimen/statusBarElevation">

Зауважте атрибути висоти та висоти, вони будуть встановлені у значеннях, значення-v19, значення-v21 далі вниз.

Додайте цей макет до макета своєї діяльності, використовуючи include, main_activity.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/Black" >

<include layout="@layout/status_bar"/>
<include android:id="@+id/app_bar" layout="@layout/app_bar"/>
//The rest of your layout       
</RelativeLayout>

На Панелі інструментів додайте атрибут верхнього поля:

<android.support.v7.widget.Toolbar 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="?android:attr/actionBarSize"
android:background="@color/primaryColor"
app:theme="@style/MyCustomToolBarTheme"
app:popupTheme="@style/ThemeOverlay.AppCompat.Dark"
android:elevation="@dimen/toolbarElevation"
android:layout_marginTop="@dimen/appBarTopMargin"
android:textDirection="ltr"
android:layoutDirection="ltr">

У своєму додаткуTheme style-v19.xml та styles-v21.xml додайте вікноTranslucent attr:

styles-v19.xml, v21:

<resources>
<item name="android:windowTranslucentStatus">true</item>
</resources>

І нарешті, у ваші параметри, dimens-v19, dimens-v21, додайте значення для панелі інструментів topMargin та висоти statusBarHeight: dimens.xml менше ніж KitKat:

<resources>
<dimen name="toolbarElevation">4dp</dimen>
<dimen name="appBarTopMargin">0dp</dimen>
<dimen name="statusBarHeight">0dp</dimen>
</resources>

Висота рядка стану завжди становить 24dp-розмір-v19.xml для KitKat та вище:

<resources>
<dimen name="statusBarHeight">24dp</dimen>
<dimen name="appBarTopMargin">24dp</dimen>
</resources>

dimens-v21.xml для Lolipop, просто додайте висоту, якщо потрібно:

<resources>
<dimen name="statusBarElevation">4dp</dimen>
</resources>

Це результат для Jellybean KitKat та Lollipop:

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


Тож замість того, щоб ставити чек у код, ви ввели його в XML. Ви вирішите працювати над Кіткатом, як і те, що він отримав.
андроїд розробник

26

Ви можете використовувати цей простий код:

Одномісний в Котліні:

window.statusBarColor = ContextCompat.getColor(this, R.color.colorName)

Оригінальна відповідь за допомогою Java та перевірка версії вручну:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    getWindow().setStatusBarColor(getResources().getColor(R.color.colorAccentDark_light, this.getTheme()));
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    getWindow().setStatusBarColor(getResources().getColor(R.color.colorAccentDark_light));
}

Ви можете додатково спростити це за допомогою ContextCompat. У Котліні це якраз так:window.statusBarColor = ContextCompat.getColor(this, R.color.colorName)
сунадорер

До того моменту, як я це написав, я ще не пробував kotlin.Чому б ви не редагували відповідь, і я можу її схвалити :)
steve moretz

Гарна ідея. Я включив свою пропозицію у відповідь як простий посилання для майбутніх відвідувачів
sunadorer

колір рядка стану змінено вище Build.VERSION_CODES.M. не працює нижче Lollipop
Мухаммед Харіс

@MuhammedHaris це спрацьовує. Ви використовуєте код kotlin або java?
steve moretz

23

Просто створіть нову тему в res / values ​​/ styles.xml, де ви зміните "colorPrimaryDark", який є кольором рядка стану:

<style name="AppTheme.GrayStatusBar" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="colorPrimaryDark">@color/colorGray</item>
</style>

І змініть тему активності в AndroidManifest.xml на потрібну, при наступній діяльності ви можете змінити колір назад на початковий, вибравши оригінальну тему:

<activity
    android:name=".LoginActivity"
    android:theme="@style/AppTheme.GrayStatusBar" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

Ось як має виглядати ваш res / values ​​/ color.xml :

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#c6d6f0</color>
    <color name="colorGray">#757575</color>
</resources>

1
Я думаю, що це найпростіше, але чисте рішення. Не потрібно мати мінімальний рівень API 21 , просто просте переосмислення. Заслуговує на більшу кількість голосів.
tahsinRupam

Це не спрацювало під час роботи на рівні Nougat та api, встановленому на 19. Це діяло, якщо я встановив android: topic під вузлом програми в маніфесті.
AndroidDev

18

Щоб змінити колір вищевказаного льодяника, просто додайте його до своїх стилів.xml

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

але пам’ятайте , якщо ви хочете мати світлий колір для рядка стану, додайте і цей рядок

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

1
Дякую, корисна відповідь теж.
Андрій Росте

16

Ви можете змінити колір рядка стану за допомогою цієї функції. працює на android L означає API 21 і вище і потребує кольоровий рядок, такий як "#ffffff".

private void changeStatusBarColor(String color){
    if (Build.VERSION.SDK_INT >= 21) {
        Window window = getWindow();
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.setStatusBarColor(Color.parseColor(color));
    }
}

15

У мене була така вимога: Програмно змінювати колір рядка стану, зберігаючи його прозорим , щоб дозволити Навігаційному ящику намалювати перекриття прозорої смуги стану.

Я не можу зробити це за допомогою API

getWindow().setStatusBarColor(ContextCompat.getColor(activity ,R.color.my_statusbar_color)

Якщо ви позначите тут у стеці переповнення всіх перед цим рядком коду, встановіть значення прозорості рядка стану

getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)

Я можу керувати кольором та прозорістю рядка стану, як це:

  • Android 4: зробити це не так багато, тому що ви не можете керувати кольором рядка стану за допомогою API ... єдине, що ви можете зробити, це встановити рядок стану як напівпрозорий і перемістити кольоровий елемент інтерфейсу користувача під статусом бар. Для цього вам потрібно пограти

    android:fitsSystemWindows="false"

    у вашому головному макеті. Це дозволяє вам намалювати макет під рядком стану. Тоді вам потрібно пограти з деякими накладками з вершиною вашого основного макета.

  • Android 5 і вище: вам потрібно визначити стиль

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

    це дозволяє ящику навігації перекривати рядок стану.

    Потім, щоб змінити колір, зберігаючи прозорий рядок стану, потрібно встановити колір рядка стану

    drawerLayout.setStatusBarBackgroundColor(ContextCompat.getColor(activity, R.color.my_statusbar_color))

    де DrawerLayout визначено так

    <android.support.v4.widget.DrawerLayout
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true">

Це працювало для мене без <item name="android:windowDrawsSystemBarBackgrounds">true</item>. У будь-якому разі, після днів пошуку я знайшов щось, що справді працює (на даний момент перевірено лише на Lolllipop). Спасибі
DenisGL

у мене була така ж проблема, і ваша відповідь допомогла мені вирішити це.
А.Гун

7

Відредагуйте colorPrimary у кольорах.xml у Значеннях до того кольору, яким ви бажаєте бути Рядок стану. Наприклад:

   <resources>
<color name="colorPrimary">#800000</color> // changes the status bar color to Burgundy
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="red">#FF0000</color>
<color name="white">#FFFFFF</color>
<color name="cream">#fffdd0</color>
<color name="burgundy">#800000</color>


7

Щоб змінити колір рядка стану, перейдіть до res/values-v21/styles.xmlта колір рядка стану

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light">
        <item name="colorPrimary">@color/color_primary</item>
        <item name="colorPrimaryDark">@color/color_secondary</item>
        <item name="colorAccent">@color/color_accent</item>
        <item name="android:statusBarColor">#0000FF</item>
    </style>
</resources>

Гей, ти можеш мені допомогти? Я не маю уявлення про Android і зараз не можу почати вчитися. У мене простий додаток відьом запускає файл HTML. Я вмираю змінити колір рядка стану, тому що це верх і низ на # 000 жахливі для моєї палети. Але я просто не можу, я навіть не можу знайти файл styles.xml ... Якщо я можу надіслати вам свій apk, і ви встановите його мені, я буду вдячний!
Тіаго Субра

6

Якщо ви хочете програмно змінити колір рядка стану (і за умови, що на пристрої є Android 5.0). Це простий спосіб змінити статусBarColor від будь-якої діяльності та дуже прості методи, коли різні фрагменти мають різний колір рядка стану.

 /**
 * @param colorId id of color
 * @param isStatusBarFontDark Light or Dark color
 */
fun updateStatusBarColor(@ColorRes colorId: Int, isStatusBarFontDark: Boolean = true) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        val window = window
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
        window.statusBarColor = ContextCompat.getColor(this, colorId)
        setSystemBarTheme(isStatusBarFontDark)
    }
}

/** Changes the System Bar Theme.  */
@RequiresApi(api = Build.VERSION_CODES.M)
private fun setSystemBarTheme(isStatusBarFontDark: Boolean) {
    // Fetch the current flags.
    val lFlags = window.decorView.systemUiVisibility
    // Update the SystemUiVisibility depending on whether we want a Light or Dark theme.
    window.decorView.systemUiVisibility = if (isStatusBarFontDark) lFlags and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv() else lFlags or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
}

5

Якщо ви хочете працювати на Android 4.4 і вище, спробуйте це. Я посилаюся на відповідь Harpreet і це посилання. Android та прозорий рядок стану

По-перше, виклик методу setStatusBarColored у методі onCreate діяльності (я ставлю його до класу util). Я використовую зображення тут, ви можете змінити його, щоб використовувати колір.

public static void setStatusBarColored(Activity context) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
    {
        Window w = context.getWindow();
        w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        int statusBarHeight = getStatusBarHeight(context);

        View view = new View(context);
        view.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        view.getLayoutParams().height = statusBarHeight;
        ((ViewGroup) w.getDecorView()).addView(view);
        view.setBackground(context.getResources().getDrawable(R.drawable.navibg));
    }
}

public static int getStatusBarHeight(Activity context) {
    int result = 0;
    int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0) {
        result = context.getResources().getDimensionPixelSize(resourceId);
    }
    return result;
}

Перед: раніше

Після: після

Колір рядка стану було змінено, але панель навігації відрізана, тому нам потрібно встановити поле або зміщення навігаційної панелі методом onCreate.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, (int)(this.getResources().getDimension(R.dimen.navibar_height)));
        layoutParams.setMargins(0, Utils.getStatusBarHeight(this), 0, 0);

        this.findViewById(R.id.linear_navi).setLayoutParams(layoutParams);
    }

Тоді рядок стану буде виглядати приблизно так.

Рядок стану


4

Це те, що працювало для мене в KitKat та з хорошими результатами.

public static void setTaskBarColored(Activity context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
        {
            Window w = context.getWindow();
            w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            //status bar height
            int statusBarHeight = Utilities.getStatusBarHeight(context);

            View view = new View(context);
            view.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            view.getLayoutParams().height = statusBarHeight;
            ((ViewGroup) w.getDecorView()).addView(view);
            view.setBackgroundColor(context.getResources().getColor(R.color.colorPrimaryTaskBar));
        }
    }

2

Ще одне рішення:

final View decorView = w.getDecorView();
View view = new View(BaseControllerActivity.this);
final int statusBarHeight = UiUtil.getStatusBarHeight(ContextHolder.get());
view.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, statusBarHeight));
view.setBackgroundColor(colorValue);
((ViewGroup)decorView).addView(view);

Чи буде це працювати на планшетах, де рядок стану знаходиться внизу екрана?
guy.gc

6
що тут 'w' та 'UiUtil'?
Манав Патадія

2

змінити colorPrimaryDark на колір бажання у файл res / values ​​/ styles.xml

    <resources>
        <color name="colorPrimary">#800000</color>
        <color name="colorPrimaryDark">#303F9F</color> //This Line
        <color name="colorAccent">#FF4081</color>
        <color name="red">#FF0000</color>
        <color name="white">#FFFFFF</color>
       <color name="cream">#fffdd0</color>
       <color name="burgundy">#800000</color>
    </resources>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.