棒棒糖:在状态栏后面绘制,颜色设置为透明
Lollipop : draw behind statusBar with its color set to transparent
我已将我的状态栏颜色设置为仅在我的主题中使用以下行的 Lollipop 透明:
<item name="android:statusBarColor">@android:color/transparent</item>
现在我需要在它后面绘制,但我无法在它后面绘制任何视图。我知道如何使用 windowTranslucentStatus
属性来做到这一点,但不想使用此属性,因为它会忽略设置为透明的状态栏的颜色。
你可以使用 ScrimInsetFrameLayout
android:fitsSystemWindows="true" 应该设置在稀松布布局上!
而不是
<item name="android:statusBarColor">@android:color/transparent</item>
使用以下内容:
<item name="android:windowTranslucentStatus">true</item>
并确保移除 'MainActivity' 布局中的顶部填充(默认添加)。
请注意,这不会使状态栏完全透明,状态栏上仍会覆盖 "faded black"。
方法一:
要实现完全透明的状态栏,就得用statusBarColor
,API21及以上才有。 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>
方法二:
如果您只需要在状态栏下方绘制背景图片,而不是在其后面放置视图,只需将 activity 的主题背景设置为所需图片即可并设置状态栏透明度,如方法#1 所示。这是我几个月前为 Android Police article 创建屏幕截图的方法。
方法三:
如果您必须忽略某些布局的标准系统插图,同时让它们在其他布局中工作,唯一可行的方法是使用经常链接的 ScrimInsetsFrameLayout
class .当然,class 中所做的一些事情并非对所有场景都是必需的。例如,如果您不打算使用合成状态栏覆盖,只需注释掉 init()
方法中的所有内容,不要费心向 attrs.xml 文件中添加任何内容。我已经看到这种方法有效,但我认为您会发现它带来了一些其他影响,可能需要大量工作才能解决。
我还看到您反对包装多个布局。在将一个布局包裹在另一个布局中的情况下,高度和宽度都为 match_parent
,性能影响微不足道,无需担心。无论如何,您可以通过将 FrameLayout
扩展的 class 更改为您喜欢的任何其他类型的布局 class 来完全避免这种情况。它会工作得很好。
这适用于我的情况
// 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 Studio 1.4,带有样板代码的模板项目会在您的 AppbarLayout and/or 工具栏上设置 Overlay
主题。它们还通过 fitSystemWindow
attribute = true 设置为在状态栏后面呈现。这将导致仅工具栏直接呈现在状态栏下方,而其他所有内容都将呈现在工具栏下方。所以上面提供的解决方案不会单独工作。您必须进行以下更改。
- 移除工具栏的 Overlay 主题或将其更改为非叠加主题。
将以下代码放入您的 styles-21.xml 文件中。
@android:color/transparent
将此主题分配给包含导航抽屉的 activity
AndroidManifest.xml 文件。
这将使导航抽屉呈现在透明状态栏后面。
与发布的一些解决方案类似,但在我的例子中,我将状态栏设为透明,并用一些负边距固定操作栏的位置
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"
我遇到了同样的问题,所以我创建了在状态栏后面绘制的 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);
}
Cody Toombs 几乎 的解决方案对我有用。我不确定这是否与 Xamarin 相关,但我现在有一个可接受的解决方案:
这是我的设置:
我有一个 Android 项目,我在其中引用了 Android.Support v4 和 v7 包。我定义了两种样式:
values/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>
values-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>
Android清单目标"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>
最后是 Main Activity 中的代码:
[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);
我花了很多时间来做对,事实上太多了。希望这个答案能帮助任何试图实现同样目标的人。
正确的解决方案是将 Activity 标签下的 XML 中的 属性 更改为以下样式。很管用
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
这是我用来完成此任务的主题:
<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>
有一个很好的库 StatusBarUtil from @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>
有关更多信息,请下载 demo or clone from github page 并使用所有功能。
注意:支持KitKat及以上版本。
希望对其他人有所帮助!
@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"
布局的根视图。
您需要做的就是在您的主题中设置这些属性
<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()
,接受的答案非常有效。
我将在此处添加更多信息。最新的 Android 开发使得处理状态栏中的许多情况变得非常容易。以下是我对 styles.xml
的观察
- 背景色:对于SDK 21+,很多回答都提到,
<item name="android:windowTranslucentStatus">true</item>
会让状态栏透明显示在[=57=前面].您的 Activity 将占据顶部的整个 space。
背景颜色:同样,对于 SDK 21+,<item name="android:statusBarColor">@color/your_color</item>
只会为您的状态栏添加颜色,而不会影响任何其他内容。
然而,在后来的设备 (Android M/+) 中,图标 开始出现深浅不一。如果您覆盖 values-23
文件夹中的 styles.xml
文件并添加 <item name="android:windowLightStatusBar">true</item>
.[=35,OS 可以为 SDK 23/+ 的图标提供更深的灰色阴影=]
这样,如果您的状态栏颜色较浅(想想有多少 google 应用程序具有浅色背景,但图标却以灰色显示,那么您将为用户提供更明显的状态栏).
如果您通过点 #2
为状态栏添加颜色,我建议您使用它
在最新的设备中,SDK 29/+ 带有系统范围的浅色和深色主题,可由用户控制。作为开发者,我们还应该在新的 values-night
文件夹中覆盖我们的样式文件,为用户提供两种不同的体验。
在这里,我再次发现第 2 点在提供 "background color to status bar" 方面是有效的。但是系统没有改变我的应用程序状态栏图标的颜色。由于我今天的风格版本由较浅的主题组成,这意味着用户将遭受低可见度(较浅背景上的白色图标)
这个问题可以通过使用第 3 点方法或覆盖 values-29
文件夹中的样式文件并使用更新的 api <item name="android:enforceStatusBarContrast">true</item>
来解决。如果您的背景颜色太浅,这将自动对图标强制使用灰色调。
我已将我的状态栏颜色设置为仅在我的主题中使用以下行的 Lollipop 透明:
<item name="android:statusBarColor">@android:color/transparent</item>
现在我需要在它后面绘制,但我无法在它后面绘制任何视图。我知道如何使用 windowTranslucentStatus
属性来做到这一点,但不想使用此属性,因为它会忽略设置为透明的状态栏的颜色。
你可以使用 ScrimInsetFrameLayout
android:fitsSystemWindows="true" 应该设置在稀松布布局上!
而不是
<item name="android:statusBarColor">@android:color/transparent</item>
使用以下内容:
<item name="android:windowTranslucentStatus">true</item>
并确保移除 'MainActivity' 布局中的顶部填充(默认添加)。
请注意,这不会使状态栏完全透明,状态栏上仍会覆盖 "faded black"。
方法一:
要实现完全透明的状态栏,就得用statusBarColor
,API21及以上才有。 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>
方法二:
如果您只需要在状态栏下方绘制背景图片,而不是在其后面放置视图,只需将 activity 的主题背景设置为所需图片即可并设置状态栏透明度,如方法#1 所示。这是我几个月前为 Android Police article 创建屏幕截图的方法。
方法三:
如果您必须忽略某些布局的标准系统插图,同时让它们在其他布局中工作,唯一可行的方法是使用经常链接的 ScrimInsetsFrameLayout
class .当然,class 中所做的一些事情并非对所有场景都是必需的。例如,如果您不打算使用合成状态栏覆盖,只需注释掉 init()
方法中的所有内容,不要费心向 attrs.xml 文件中添加任何内容。我已经看到这种方法有效,但我认为您会发现它带来了一些其他影响,可能需要大量工作才能解决。
我还看到您反对包装多个布局。在将一个布局包裹在另一个布局中的情况下,高度和宽度都为 match_parent
,性能影响微不足道,无需担心。无论如何,您可以通过将 FrameLayout
扩展的 class 更改为您喜欢的任何其他类型的布局 class 来完全避免这种情况。它会工作得很好。
这适用于我的情况
// 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 Studio 1.4,带有样板代码的模板项目会在您的 AppbarLayout and/or 工具栏上设置 Overlay
主题。它们还通过 fitSystemWindow
attribute = true 设置为在状态栏后面呈现。这将导致仅工具栏直接呈现在状态栏下方,而其他所有内容都将呈现在工具栏下方。所以上面提供的解决方案不会单独工作。您必须进行以下更改。
- 移除工具栏的 Overlay 主题或将其更改为非叠加主题。
将以下代码放入您的 styles-21.xml 文件中。
@android:color/transparent
将此主题分配给包含导航抽屉的 activity AndroidManifest.xml 文件。
这将使导航抽屉呈现在透明状态栏后面。
与发布的一些解决方案类似,但在我的例子中,我将状态栏设为透明,并用一些负边距固定操作栏的位置
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"
我遇到了同样的问题,所以我创建了在状态栏后面绘制的 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);
}
Cody Toombs 几乎 的解决方案对我有用。我不确定这是否与 Xamarin 相关,但我现在有一个可接受的解决方案:
这是我的设置:
我有一个 Android 项目,我在其中引用了 Android.Support v4 和 v7 包。我定义了两种样式:
values/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>
values-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>
Android清单目标"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>
最后是 Main Activity 中的代码:
[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);
我花了很多时间来做对,事实上太多了。希望这个答案能帮助任何试图实现同样目标的人。
正确的解决方案是将 Activity 标签下的 XML 中的 属性 更改为以下样式。很管用
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
这是我用来完成此任务的主题:
<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>
有一个很好的库 StatusBarUtil from @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>
有关更多信息,请下载 demo or clone from github page 并使用所有功能。
注意:支持KitKat及以上版本。
希望对其他人有所帮助!
@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"
布局的根视图。
您需要做的就是在您的主题中设置这些属性
<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()
,接受的答案非常有效。
我将在此处添加更多信息。最新的 Android 开发使得处理状态栏中的许多情况变得非常容易。以下是我对 styles.xml
- 背景色:对于SDK 21+,很多回答都提到,
<item name="android:windowTranslucentStatus">true</item>
会让状态栏透明显示在[=57=前面].您的 Activity 将占据顶部的整个 space。 背景颜色:同样,对于 SDK 21+,
<item name="android:statusBarColor">@color/your_color</item>
只会为您的状态栏添加颜色,而不会影响任何其他内容。然而,在后来的设备 (Android M/+) 中,图标 开始出现深浅不一。如果您覆盖
values-23
文件夹中的styles.xml
文件并添加<item name="android:windowLightStatusBar">true</item>
.[=35,OS 可以为 SDK 23/+ 的图标提供更深的灰色阴影=] 这样,如果您的状态栏颜色较浅(想想有多少 google 应用程序具有浅色背景,但图标却以灰色显示,那么您将为用户提供更明显的状态栏).
如果您通过点 #2 为状态栏添加颜色,我建议您使用它
在最新的设备中,SDK 29/+ 带有系统范围的浅色和深色主题,可由用户控制。作为开发者,我们还应该在新的
values-night
文件夹中覆盖我们的样式文件,为用户提供两种不同的体验。
在这里,我再次发现第 2 点在提供 "background color to status bar" 方面是有效的。但是系统没有改变我的应用程序状态栏图标的颜色。由于我今天的风格版本由较浅的主题组成,这意味着用户将遭受低可见度(较浅背景上的白色图标)
这个问题可以通过使用第 3 点方法或覆盖values-29
文件夹中的样式文件并使用更新的 api<item name="android:enforceStatusBarContrast">true</item>
来解决。如果您的背景颜色太浅,这将自动对图标强制使用灰色调。