Lollipop: рисовать позади statusBar с его цветом, установленным на прозрачный
Я установил цвет statusBar прозрачным для Lollipop только со следующей строкой в моей теме:
<item name="android:statusBarColor">@android:color/transparent</item>
Теперь мне нужно потянуться за ним, но я не могу получить ни одного взгляда за ним. Я знаю, как это сделать с помощью свойства windowTranslucentStatus
, но не хочу использовать это свойство, так как оно будет игнорировать цвет установленного в statusBar прозрачного.
Ответы
Ответ 1
Метод # 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. Он будет работать нормально.
Ответ 2
Это сработало для моего случая
// 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
Ответ 3
Попробуйте эту тему
<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"
Ответ 4
Вместо
<item name="android:statusBarColor">@android:color/transparent</item>
Используйте следующее:
<item name="android:windowTranslucentStatus">true</item>
И не забудьте удалить верхнюю прокладку (которая добавляется по умолчанию) на макете "MainActivity".
Обратите внимание, что это не делает панель состояния полностью прозрачной, и в вашей строке состояния по-прежнему будет "выцветший черный" наложение.
Ответ 5
Решение от 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);
Я потратил много времени на правильное решение, слишком много времени. Надеюсь, этот ответ поможет любому, кто пытается достичь того же.
Ответ 6
У меня была та же проблема, поэтому я создал 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);
}
Ответ 7
Ответ @Cody Toombs приводит к проблеме, которая приносит макет за панель навигации. Итак, я нашел это решение, данное @Kriti
здесь приведен фрагмент кода Котлина для него:
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"
корневой вид вашего макета.
Ответ 8
Вы можете использовать ScrimInsetFrameLayout
https://github.com/google/iosched/blob/master/android/src/main/java/com/google/samples/apps/iosched/ui/widget/ScrimInsetsFrameLayout.java
android: fitsSystemWindows = "true" должен быть установлен на компоновке scrim!
Ответ 9
Как и в некоторых из размещенных решений, но в моем случае я сделал прозрачную строку состояния и зафиксировал положение панели действий с некоторым отрицательным отрывом
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"
Ответ 10
Существует хорошая библиотека StatusBarUtil из @laobie, которая помогает легко нарисовать изображение в StatusBar.
Просто добавьте в свой build.gradle
:
compile 'com.jaeger.statusbarutil:library:1.4.0'
Затем в наборе действий
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 и выше.
Надеюсь, что это поможет кому-то еще!
Ответ 11
С Android Studio 1.4 проект шаблона с кодовым таблицей кодов устанавливает Overlay
тему на панели AppbarLayout и/или панели инструментов. Они также должны отображаться за строкой состояния fitSystemWindow
attribute = true. Это приведет к тому, что панель инструментов будет отображаться непосредственно под панелью состояния, а все остальное будет отображаться под панелью инструментов. Поэтому приведенные выше решения не будут работать самостоятельно. Вам нужно будет внести следующие изменения.
- Удалите тему Overlay или измените ее на тему без наложения для панели инструментов.
-
Поместите следующий код в файл styles-21.xml.
@android: Цвет/прозрачный
-
Назначьте эту тему в действие, содержащее ящик навигации в
файл AndroidManifest.xml.
Это заставит ящик навигации отображать за прозрачной панелью состояния.
Ответ 12
Все, что вам нужно сделать, это установить эти свойства в своей теме
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
Ответ 13
Принятый ответ сработал для меня, используя CollapsingToolbarLayout. Важно отметить, что setSytstemUiVisibility()
переопределяет любые предыдущие вызовы этой функции. Поэтому, если вы используете эту функцию где-то еще для того же представления, вам необходимо включить флаги View.SYSTEM_UI_FLAG_LAYOUT_STABLE
и View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
, иначе они будут переопределены новым вызовом.
Это было так для меня, и как только я добавил два флага в другое место, где я вызывал setSystemUiVisibility()
, принятый ответ сработал отлично.
Ответ 14
Вот тема, которую я использую для этого:
<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>
Ответ 15
Правильное решение состоит в том, чтобы изменить свойство в XML под тегом Activity ниже в стиле. Он просто работает
android:theme="@style/Theme.AppCompat.Light.NoActionBar"