Я установил прозрачный цвет statusBar для Lollipop только со следующей строкой в моей теме:
<item name="android:statusBarColor">@android:color/transparent</item>
Теперь мне нужно нарисовать за ним, но я не могу нарисовать вид за ним. Я знаю, как это сделать со windowTranslucentStatus
свойством, но не хочу использовать это свойство, так как в этом случае цвет statusBar, установленный на transparent, будет игнорироваться.
android:fitsSystemWindows="true"
Ответы:
Способ №1:
Чтобы получить полностью прозрачную строку состояния, вы должны использовать
statusBarColor
, что доступно только в API 21 и выше.windowTranslucentStatus
доступен в API 19 и выше, но добавляет тонированный фон для строки состояния. Тем не менее, установкаwindowTranslucentStatus
делает достичь одну вещь , которая меняетсяstatusBarColor
на прозрачный не делает: он устанавливаетSYSTEM_UI_FLAG_LAYOUT_STABLE
иSYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
флаги. Самый простой способ добиться того же эффекта - установить эти флаги вручную, что эффективно отключает вставки, налагаемые системой макета Android, и оставляет вас на произвол судьбы.Вы вызываете эту строку в своем
onCreate
методе:getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
Не забудьте также установить прозрачность в /res/values-v21/styles.xml:
<item name="android:statusBarColor">@android:color/transparent</item>
Или программно установите прозрачность:
getWindow().setStatusBarColor(Color.TRANSPARENT);
Хорошая сторона этого подхода заключается в том, что те же макеты и конструкции можно использовать и в API 19, заменив прозрачную строку состояния тонированной полупрозрачной строкой состояния.
<item name="android:windowTranslucentStatus">true</item>
Способ №2:
Если вам нужно только нарисовать фоновое изображение под строкой состояния, вместо того, чтобы размещать представление за ним, это можно сделать, просто установив фон темы вашего действия на желаемое изображение и установив прозрачность строки состояния, как показано в методе # 1. Это был метод, который я использовал для создания снимков экрана для статьи об Android Police, опубликованной несколько месяцев назад.
Способ №3:
Если вам нужно игнорировать стандартные системные вставки для одних макетов, сохраняя их работоспособность в других, единственный жизнеспособный способ сделать это - работать с часто связываемым
ScrimInsetsFrameLayout
классом. Конечно, некоторые вещи, выполняемые в этом классе, необходимы не для всех сценариев. Например, если вы не планируете использовать наложение синтетической строки состояния, просто закомментируйте все вinit()
методе и не добавляйте ничего в файл attrs.xml. Я видел, как этот подход работает, но я думаю, вы обнаружите, что он имеет некоторые другие последствия, которые, возможно, потребует много работы.Я также заметил, что вы против упаковки нескольких макетов. В случае обертывания одного макета внутри другого, когда оба имеют
match_parent
высоту и ширину, последствия для производительности слишком тривиальны, чтобы о них беспокоиться. Тем не менее, вы можете полностью избежать этой ситуации, изменив класс, из которого он расширяется,FrameLayout
на любой другой тип класса Layout, который вам нравится. Он будет работать нормально.источник
SYSTEM_UI_FLAG_LAYOUT_STABLE
иSYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
флаги было решение , которое я искал.CollapsingToolbarLayout
иToolbar
: строка состояния остается не полностью прозрачной иandroid:statusBarColor
не действуетЭто сработало в моем случае
// Create/Set toolbar as actionbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); // Check if the version of Android is Lollipop or higher if (Build.VERSION.SDK_INT >= 21) { // Set the status bar to dark-semi-transparentish getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); // Set paddingTop of toolbar to height of status bar. // Fixes statusbar covers toolbar issue toolbar.setPadding(0, getStatusBarHeight(), 0, 0); }
// A method to find height of the status bar public int getStatusBarHeight() { int result = 0; int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { result = getResources().getDimensionPixelSize(resourceId); } return result; }
Для получения дополнительной информации о работе со статусбарами: youtube.com/watch?v=_mGDMVRO3iE
источник
Попробуйте эту тему
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item> <item name="colorPrimaryDark">@android:color/transparent</item> <item name="colorPrimary">@color/md_blue_200</item> <item name="android:windowDrawsSystemBarBackgrounds">true</item> <item name="android:statusBarColor">@android:color/transparent</item> <item name="android:windowTranslucentStatus">true</item> </style>
Убедитесь, что ваш макет установлен
android:fitsSystemWindows="false"
источник
android:fitsSystemWindows="false"
разрезает панель инструментов пополам.Вместо того
<item name="android:statusBarColor">@android:color/transparent</item>
Используйте следующее:
<item name="android:windowTranslucentStatus">true</item>
И не забудьте удалить верхний отступ (который добавлен по умолчанию) в макете MainActivity.
Обратите внимание, что это не делает строку состояния полностью прозрачной, и на строке состояния все равно будет «блеклый черный» наложение.
источник
<item name="android:windowTranslucentStatus">true</item>
он заставляет Android помещать блеклый черный фон под строку состояния, чего я не ищу. Как бы то ни было, чтобы не было этого черного выцветшего фона?Решение от Cody Toombs почти помогло мне. Я не уверен, связано ли это с Xamarin или нет, но теперь у меня есть приемлемое решение:
Это моя установка:
У меня есть проект Android, в котором я сослался на пакеты Android.Support v4 и v7. У меня определены два стиля:
значения / styles.xml:
<?xml version="1.0" encoding="UTF-8" ?> <resources> <style name="MyStyle" parent="@style/Theme.AppCompat.Light.NoActionBar"> <item name="android:windowTranslucentStatus">true</item> </style> </resources>
значения-v21 / styles.xml:
<?xml version="1.0" encoding="UTF-8" ?> <resources> <style name="MyStyle" parent="@style/Theme.AppCompat.Light.NoActionBar"> <item name="android:statusBarColor">@android:color/transparent</item> </style> </resources>
AndroidManifest нацелен на MyStyle:
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.agn.test.test"> <uses-sdk android:minSdkVersion="10" /> <application android:allowBackup="true" android:icon="@mipmap/icon" android:label="@string/app_name" android:theme="@style/MyStyle"> </application> </manifest>
И, наконец, код в основном действии:
[Activity (Label = "Test", MainLauncher = true, Icon = "@mipmap/icon")] public class MainActivity : Activity { protected override void OnCreate (Bundle savedInstanceState) { base.OnCreate (savedInstanceState); SetContentView (Resource.Layout.Main); //Resource.Layout.Main is just a regular layout, no additional flags. Make sure there is something in there like an imageView, so that you can see the overlay. var uiOptions = (int)Window.DecorView.SystemUiVisibility; uiOptions ^= (int)SystemUiFlags.LayoutStable; uiOptions ^= (int)SystemUiFlags.LayoutFullscreen; Window.DecorView.SystemUiVisibility = (StatusBarVisibility)uiOptions; Window.AddFlags (WindowManagerFlags.DrawsSystemBarBackgrounds); } }
Обратите внимание, что я установил флаг DrawsSystemBarBackgrounds, в этом вся разница
Window.AddFlags (WindowManagerFlags.DrawsSystemBarBackgrounds);
Я потратил много времени на то, чтобы все исправить, на самом деле, слишком много времени. Надеюсь, этот ответ поможет любому, кто пытается добиться того же.
источник
android:windowTranslucentStatus
требуется уровень API 19 или выше, как это возможно, что вы используете его в своих values / styles.xml , имеяandroid:minSdkVersion
10?Ответ @Cody Toombs приводит к проблеме, из-за которой макет находится за панелью навигации. Итак, я обнаружил, что использую это решение, данное @Kriti
вот фрагмент кода Kotlin для того же:
if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) { setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, true) } if (Build.VERSION.SDK_INT >= 19) { window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN } if (Build.VERSION.SDK_INT >= 21) { setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, false) getWindow().setStatusBarColor(Color.TRANSPARENT) } private fun setWindowFlag(activity: Activity, bits: Int, on: Boolean) { val win: Window = activity.getWindow() val winParams: WindowManager.LayoutParams = win.getAttributes() if (on) { winParams.flags = winParams.flags or bits } else { winParams.flags = winParams.flags and bits.inv() } win.setAttributes(winParams) }
Вам также необходимо добавить
android:fitsSystemWindows="false"
корневой вид вашего макета.
источник
У меня была такая же проблема, поэтому я создаю ImageView, который рисует за API строки состояния 19+
Установите собственное изображение за строкой состояния gist.github.com
public static void setTransparent(Activity activity, int imageRes) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { return; } // set flags if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); activity.getWindow().setStatusBarColor(Color.TRANSPARENT); } else { activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); } // get root content of system window //ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0); // rootView.setFitsSystemWindows(true); // rootView.setClipToPadding(true); ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content); if (contentView.getChildCount() > 1) { contentView.removeViewAt(1); } // get status bar height int res = activity.getResources().getIdentifier("status_bar_height", "dimen", "android"); int height = 0; if (res != 0) height = activity.getResources().getDimensionPixelSize(res); // create new imageview and set resource id ImageView image = new ImageView(activity); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, height); image.setLayoutParams(params); image.setImageResource(imageRes); image.setScaleType(ScaleType.MATRIX); // add image view to content view contentView.addView(image); // rootView.setFitsSystemWindows(true); }
источник
Вы можете использовать ScrimInsetFrameLayout
https://github.com/google/iosched/blob/master/android/src/main/java/com/google/samples/apps/iosched/ui/widget/ScrimInsetsFrameLayout.java
android: fitsSystemWindows = "true" должен быть установлен в макете холста!
источник
RelativeLayout
вместоFrameLayout
?Подобно некоторым из опубликованных решений, но в моем случае я сделал строку состояния прозрачной и исправил положение панели действий с некоторым отрицательным полем.
if (Build.VERSION.SDK_INT >= 21) { getWindow().setStatusBarColor(Color.TRANSPARENT); FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) toolbar.getLayoutParams(); lp.setMargins(0, -getStatusBarHeight(), 0, 0); }
И я использовал на панели инструментов и в корневом представлении
android:fitsSystemWindows="true"
источник
Есть хорошая библиотека StatusBarUtil от @laobie, которая помогает легко рисовать изображения в StatusBar.
Просто добавьте в свой
build.gradle
:compile 'com.jaeger.statusbarutil:library:1.4.0'
Затем в наборе Activity
StatusBarUtil.setTranslucentForImageView(Activity activity, int statusBarAlpha, View viewNeedOffset)
В макете
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white" android:orientation="vertical"> <ImageView android:layout_alignParentTop="true" android:layout_width="match_parent" android:adjustViewBounds="true" android:layout_height="wrap_content" android:src="@drawable/toolbar_bg"/> <android.support.design.widget.CoordinatorLayout android:id="@+id/view_need_offset" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="@android:color/transparent" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/> <!-- Your layout code --> </android.support.design.widget.CoordinatorLayout> </RelativeLayout>
Для получения дополнительной информации загрузите демо или клон со страницы github и поиграйте со всеми функциями.
Примечание. Поддержите KitKat и выше.
Надеюсь, это поможет кому-то другому!
источник
Я добавлю сюда дополнительную информацию. Последние разработки для Android позволили довольно легко обрабатывать множество случаев в строке состояния. Ниже приведены мои наблюдения
styles.xml
<item name="android:windowTranslucentStatus">true</item>
строка состояния будет прозрачной и отображаться перед пользовательским интерфейсом. Ваша Activity займет все пространство вверху.Цвет фона : опять же, для SDK 21+
<item name="android:statusBarColor">@color/your_color</item>
просто придаст цвет вашей строке состояния, не влияя ни на что другое.Однако на более поздних устройствах (Android M / +) значки стали иметь разные оттенки. ОС может придать более темный оттенок серого значкам для SDK 23 / +, если вы переопределите свой
styles.xml
файл вvalues-23
папке и добавите<item name="android:windowLightStatusBar">true</item>
.Таким образом, вы предоставите своему пользователю более заметную строку состояния, если ваша строка состояния имеет светлый цвет (подумайте о том, как многие приложения Google имеют светлый фон, а значки там отображаются сероватым цветом).
Я бы посоветовал вам использовать это, если вы придаете цвет своей строке состояния через пункт 2.
В самых последних устройствах SDK 29 / + поставляется с общесистемной светлой и темной темой, управляемой пользователем. Как разработчики, мы также должны переопределить наш файл стиля в новой
values-night
папке, чтобы дать пользователю два разных опыта.Здесь я снова обнаружил, что пункт №2 эффективен в обеспечении «цвета фона для строки состояния». Но система не меняла цвет значков строки состояния для моего приложения. поскольку моя дневная версия стиля состояла из более легкой темы, это означает, что пользователи будут страдать от плохой видимости (белые значки на более светлом фоне).
Эту проблему можно решить, используя подход пункта 3 или переопределив файл стиля в
values-29
папке и используя более новый api<item name="android:enforceStatusBarContrast">true</item>
. Это автоматически приведет к сероватому оттенку значков, если цвет вашего фона слишком светлый.источник
В Android Studio 1.4 проект шаблона со стандартным кодом устанавливает
Overlay
тему на AppbarLayout и / или на панели инструментов. Они также настроены на отображение за строкой состояния с помощьюfitSystemWindow
attribute = true. Это приведет к тому, что только панель инструментов будет отображаться непосредственно под строкой состояния, а все остальное будет отображаться под панелью инструментов. Таким образом, приведенные выше решения не будут работать сами по себе. Вам нужно будет внести следующие изменения.Поместите следующий код в свой файл styles-21.xml .
@android: цвет / прозрачный
Назначьте эту тему действию, содержащему панель навигации в файле AndroidManifest.xml .
Это заставит панель навигации отображаться за прозрачной строкой состояния.
источник
Все, что вам нужно сделать, это установить эти свойства в своей теме.
<item name="android:windowTranslucentStatus">true</item> <item name="android:windowTranslucentNavigation">true</item>
источник
Принятый ответ сработал для меня с использованием CollapsingToolbarLayout. Однако важно отметить, что это
setSytstemUiVisibility()
отменяет любые предыдущие вызовы этой функции. Так что, если вы используете эту функцию где - то еще для одной и той же точки зрения, необходимо включитьView.SYSTEM_UI_FLAG_LAYOUT_STABLE
иView.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
флаги, или они будут переопределены с новым вызовом.Так было со мной, и как только я добавил два флага в другое место, куда звонил
setSystemUiVisibility()
, принятый ответ сработал отлично.источник
Вот тема, которую я использую для этого:
<style name="AppTheme" parent="@android:style/Theme.NoTitleBar"> <!-- Default Background Screen --> <item name="android:background">@color/default_blue</item> <item name="android:windowTranslucentStatus">true</item> </style>
источник
Правильное решение - изменить свойство в XML в теге Activity на стиль ниже. Это просто работает
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
источник