Lollipop:在statusBar后面绘制颜色设置为透明

alx*_*cms 131 android android-ui android-5.0-lollipop

我已经将我的statusBar颜色设置为Lollipop的透明颜色,仅在我的主题中使用以下行:

<item name="android:statusBarColor">@android:color/transparent</item>
Run Code Online (Sandbox Code Playgroud)

现在我需要在它背后绘制,但我不能得到它背后的任何视图.我知道如何使用windowTranslucentStatus属性,但不想使用此属性,因为它将忽略statusBar设置为透明的颜色.

Cod*_*mbs 370

方法#1:

要实现完全透明的状态栏,您必须使用statusBarColor,仅在API 21及更高版本上可用.windowTranslucentStatus在API 19及更高版本上可用,但它为状态栏添加了有色背景.但是,设置windowTranslucentStatus确实实现了一个改变statusBarColor为透明的东西:它设置SYSTEM_UI_FLAG_LAYOUT_STABLESYSTEM_UI_FLAG_LAYOUT_FULLSCREEN标志.获得相同效果的最简单方法是手动设置这些标志,这有效地禁用Android布局系统强加的插件,让您自己照顾自己.

您在onCreate方法中调用此行:

getWindow().getDecorView().setSystemUiVisibility(
    View.SYSTEM_UI_FLAG_LAYOUT_STABLE
    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
Run Code Online (Sandbox Code Playgroud)

一定要在/res/values-v21/styles.xml中设置透明度:

<item name="android:statusBarColor">@android:color/transparent</item>
Run Code Online (Sandbox Code Playgroud)

或者以编程方式设置透明度:

getWindow().setStatusBarColor(Color.TRANSPARENT);
Run Code Online (Sandbox Code Playgroud)

这种方法的好处在于,通过交换有色半透明状态栏的透明状态栏,也可以在API 19上使用相同的布局和设计.

<item name="android:windowTranslucentStatus">true</item>
Run Code Online (Sandbox Code Playgroud)

方法#2:

如果您只需要在状态栏下绘制背景图像,而不是在其背后放置视图,只需将活动主题的背景设置为所需图像并设置状态栏透明度即可,如方法#所示1.这是我几个月前用于为Android Police文章创建屏幕截图的方法.

方法#3:

如果你必须忽略某些布局的标准系统插入,同时保持它们在其他布局中工作,唯一可行的方法是使用经常链接的ScrimInsetsFrameLayout类.当然,在该类中完成的一些事情对于所有场景都不是必需的.例如,如果您不打算使用合成状态栏覆盖,只需注释掉init()方法中的所有内容,并且不要在attrs.xml文件中添加任何内容.我已经看到这种方法有效,但我认为你会发现它带来了一些其他影响,可能需要做很多工作才能解决.

我也看到你反对包装多个布局.如果将一个布局包装在另一个布局中,其中两个布局都具有match_parent高度和宽度,则性能影响太小而无法担心.无论如何,您可以通过将其扩展的类更改为FrameLayout您喜欢的任何其他类型的Layout类来完全避免这种情况.它会工作得很好.

  • 非常感谢,设置`SYSTEM_UI_FLAG_LAYOUT_STABLE`和`SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN`标志是我正在寻找的解决方案. (8认同)
  • 我搜索了你的第一个解决方案一个月.谢谢! (3认同)
  • 这不适用于`CollapsingToolbarLayout`和`Toolbar`:状态栏保持不完全半透明,`android:statusBarColor`不起作用 (3认同)

Mic*_*ael 41

这适用于我的情况


// 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);
}
Run Code Online (Sandbox Code Playgroud)
// 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;
}
Run Code Online (Sandbox Code Playgroud)

有关使用statusBars的详细信息,请访问:youtube.com/watch? v = _mGDMVRO3iE


  • 像这样获取状态栏高度完全不受支持,没有文档记录,并且在将来的版本中肯定会中断.请改用fitsSystemWindows ="true". (4认同)
  • 根据Chris Banes(Google工程师)的演讲,这是一个非常糟糕的主意:https://www.youtube.com/watch?v=_mGDMVRO3iE (2认同)

小智 20

试试这个主题

<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>
Run Code Online (Sandbox Code Playgroud)

请确保您的布局设置

android:fitsSystemWindows="false"
Run Code Online (Sandbox Code Playgroud)

  • 设置`android:fitsSystemWindows ="false"`将工具栏切成两半. (4认同)

Jer*_*ols 13

代替

<item name="android:statusBarColor">@android:color/transparent</item>
Run Code Online (Sandbox Code Playgroud)

使用以下内容:

<item name="android:windowTranslucentStatus">true</item>
Run Code Online (Sandbox Code Playgroud)

并确保删除"MainActivity"布局中的顶部填充(默认情况下添加).

请注意,这不会使状态栏完全透明,并且状态栏上仍会出现"褪色黑色"覆盖.

  • 当使用`<item name ="android:windowTranslucentStatus"> true </ item>`时,它会让android在状态栏下放置一个褪色的黑色背景,这不是我想要的.虽然没有这种黑色褪色背景的任何方式? (2认同)

Ger*_*urs 8

来自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>
Run Code Online (Sandbox Code Playgroud)

值-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>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

最后是主要活动中的代码:

[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);
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,我设置了DrawsSystemBarBackgrounds标志,这就完全不同了

Window.AddFlags (WindowManagerFlags.DrawsSystemBarBackgrounds); 
Run Code Online (Sandbox Code Playgroud)

我花了很多时间把它弄好,实际上花了太多时间.希望这个答案可以帮助任何人尝试实现同样的目标.


Kis*_*nki 8

@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)
}
Run Code Online (Sandbox Code Playgroud)

您还需要添加

android:fitsSystemWindows="false"
Run Code Online (Sandbox Code Playgroud)

布局的根视图。