Як змінити колір рядка стану в 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.