即使使用 windowTranslucentStatus 和 fitSystemWindows,CoordinatorLayout 也不会在状态栏后面绘制

Posted

技术标签:

【中文标题】即使使用 windowTranslucentStatus 和 fitSystemWindows,CoordinatorLayout 也不会在状态栏后面绘制【英文标题】:CoordinatorLayout not drawing behind status bar even with windowTranslucentStatus and fitsSystemWindows 【发布时间】:2016-02-13 14:43:35 【问题描述】:

我正在尝试在状态栏后面绘制视图,如下所示:

我尝试使用推荐的技术来产生这种效果,但我明白了:

从屏幕截图中可以清楚地看出,我的应用内容都没有被绘制在状态栏后面。

有趣的是,Nav Drawer 设法在状态栏后面绘制:

我做过的事情:

使用支持库小部件 - CoordinatorLayoutAppBarLayoutToolbarDrawerLayout windowTranslucentStatus 在我的应用主题中设置为 true fitsSystemWindows 在我的 CoordinatorLayout 上设置为 true

这是我的应用主题:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
  <!-- Customize your theme here. -->
  <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@android:color/transparent</item>
    <item name="colorAccent">@color/colorAccent</item>

    <item name="android:windowTranslucentStatus">true</item>
</style>

这是我的活动布局:

<android.support.v4.widget.DrawerLayout
    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:id="@+id/drawer_layout"
    android:layout_
    android:layout_
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <FrameLayout android:id="@+id/page_container"
                 android:layout_
                 android:layout_
                 android:fitsSystemWindows="true"/>

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_
        android:layout_
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

</android.support.v4.widget.DrawerLayout>

我的活动布局中的 FrameLayout 被这个片段布局替换了:

<android.support.design.widget.CoordinatorLayout
    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_
    android:layout_
    android:fitsSystemWindows="true"
    tools:context=".MainActivity">

    <FrameLayout android:layout_
                 android:layout_
                 android:paddingLeft="@dimen/activity_horizontal_margin"
                 android:paddingRight="@dimen/activity_horizontal_margin"
                 android:paddingTop="@dimen/activity_vertical_margin"
                 android:paddingBottom="@dimen/activity_vertical_margin"
                 android:background="@android:color/holo_blue_bright"
                 tools:context=".MainActivity">

        <TextView android:text="@string/lorem_ipsum"
                  android:layout_
                  android:layout_ />
    </FrameLayout>

    <android.support.design.widget.AppBarLayout
        android:layout_
        android:layout_
        app:elevation="0dp"
        android:theme="@style/AppTheme.TransparentAppBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_
            android:layout_
            android:background="@android:color/transparent"
            app:title="@string/hello_blank_fragment"
            app:popupTheme="@style/AppTheme.OverflowMenu" />

    </android.support.design.widget.AppBarLayout>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_
        android:layout_
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        android:src="@android:drawable/ic_dialog_email" />

</android.support.design.widget.CoordinatorLayout>

【问题讨论】:

尝试在抽屉布局上设置 fitSystemWindows="false"。 @mvai 我刚试了一下,似乎没有任何改变 我遇到了类似的问题,试试这个:***.com/questions/34761671/… 看到这个答案:***.com/a/47906087/2201814 【参考方案1】:

为未来的读者编辑:在 cmets 上有很多关于该主题和问题的好信息,请务必通读。

原答案: 你的主题是错误的,这就是原因。 不幸的是,如何在 Kitkat 或 Lollipop 中激活存在差异。在我的代码中,我是用 Java 完成的,但如果您想使用资源树上的 V21 文件夹,您也可以在 XML 中实现它。参数的名称将与 Java 对应的名称非常相似。

从您的 XML 和 Java 中删除 android:windowTranslucentStatus,如下所示:

   public static void setTranslucentStatusBar(Window window) 
      if (window == null) return;
      int sdkInt = Build.VERSION.SDK_INT;
      if (sdkInt >= Build.VERSION_CODES.LOLLIPOP) 
         setTranslucentStatusBarLollipop(window);
       else if (sdkInt >= Build.VERSION_CODES.KITKAT) 
         setTranslucentStatusBarKiKat(window);
      
   

  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
   private static void setTranslucentStatusBarLollipop(Window window) 
      window.setStatusBarColor(
             window.getContext()
                   .getResources()
                   .getColor(R.color. / add here your translucent color code /));
   

   @TargetApi(Build.VERSION_CODES.KITKAT)
   private static void setTranslucentStatusBarKiKat(Window window) 
      window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
   

然后你可以从你的活动中调用setTranslucentStatusBar(getWindow());

编辑:

使状态栏半透明并在其后面绘制(由于某种原因我无法理解)是 Android 中的两个独立任务。

我对我的代码进行了更多的查看,而且我肯定在我的布局中拥有更多 android:fitsSystemWindows="true" 而不仅仅是 CoordinatorLayout

下面是我的布局上的所有视图,上面有android:fitsSystemWindows="true"

协调器布局 AppBarLayout CollapsingToolbarLayout ImageView(带背景图片) FrameLayout(带有标题的内容)

所以我的建议是在您的 XML 上测试/尝试填写 android:fitsSystemWindows="true"

【讨论】:

您的技术删除了状态栏的深色背景,但它仍然没有让我的CoordinatorLayout 填充状态栏后面的区域。现在看起来像这样:i.imgur.com/koMgcm0.png?1 很抱歉,将fitsSystemWindows 应用于所有内容均无效。我什至尝试使用fitsSystemWindows 将带有ImageView 的CollapsingToolbarLayout 添加到我的片段布局中,但这也不起作用。说真的,谢谢你的帮助。我想我必须尝试一些非正统的解决方案。 我的项目也有碎片,不是这个原因。我猜你误解了 fitSystemWindows developer.android.com/reference/android/view/… 。试一试。 我让它工作了!你是对的,我误解了fitsSystemWindows。它不会扩展视图以“适应系统窗口”,它实际上要求视图避免像状态栏这样的窗口装饰。我通过从所有内容中删除 fitsSystemWindows 解决了这个问题。在我的应用主题中将windowsTranslucentStatus 设置为true 足以达到我想要的效果; fitsSystemWindows 实际上干扰了这一点。 @Bhargav 你能告诉我如何应对这种情况 DrawerLayout --> Cordinator ->AppBar ->ToolBar , LP 和 MM 它工作正常,但是对于 KK 启用 Translucent 属性,然后工具栏在它下面并在 appbar 下添加填充结果工具栏,并且 appbar 已修复,我在几种组合上尝试了 fsw 无效,我必须在主抽屉上使用 fitsystems 窗口,以便在打开抽屉时它不会显示有色 SB,建议 plz.. 【参考方案2】:

这对我来说真的很困惑,但我最终根据我的视图组合弄明白了,看起来像这样:

<android.support.v4.widget.SwipeRefreshLayout - **no fitsSystemWindow set**

<android.support.design.widget.CoordinatorLayout- android:fitsSystemWindows="true"

<android.support.design.widget.AppBarLayout - android:fitsSystemWindows="true"

<android.support.design.widget.CollapsingToolbarLayout - android:fitsSystemWindows="true"

<RelativeLayout - android:fitsSystemWindows="true"

<ImageView - android:fitsSystemWindows="true"

我还使用了 Budius 在我的应用中发布的方法来使透明状态栏正常工作:

从您的 XML 中删除 android:windowTranslucentStatus 并在 Java 中这样使用:

   public static void setTranslucentStatusBar(Window window) 
      if (window == null) return;
      int sdkInt = Build.VERSION.SDK_INT;
      if (sdkInt >= Build.VERSION_CODES.LOLLIPOP) 
         setTranslucentStatusBarLollipop(window);
       else if (sdkInt >= Build.VERSION_CODES.KITKAT) 
         setTranslucentStatusBarKiKat(window);
      
   

  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
   private static void setTranslucentStatusBarLollipop(Window window) 
      window.setStatusBarColor(
             window.getContext()
                   .getResources()
                   .getColor(R.color. / add here your translucent color code /));
   

   @TargetApi(Build.VERSION_CODES.KITKAT)
   private static void setTranslucentStatusBarKiKat(Window window) 
      window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
   

【讨论】:

你帮我解决了我的问题,因此 +1【参考方案3】:
    如果我想在 StatusBar 后面绘制,我使用 CoordinatorLayout 作为 Activity 的最父视图(android:适合SystemWindows="false")

styles.xml(v21)

<style name="MyTheme.NoActionBar.TransparentStatusBar">
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="android:statusBarColor">@android:color/transparent</item>
        <item name="android:windowTranslucentStatus">true</item>
    </style>

那么如果你想改变statubarcolor,你必须像这样删除TRANSLUENT_FLAG

Window window = activity().getWindow();
        if(showTransluent)
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.setStatusBarColor(Color.TRANSPARENT);
        else 
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.setStatusBarColor(ContextCompat.getColor(activity(), R.color.colorPrimaryDark));
        

    如果我希望 StatusBar 是半透明的并且同时保持视图远离隐藏在 StatusBar 后面,我将使用带参数的大多数父视图 FrameLayout

我的 styles.xml(v21) 看起来像

<resources>

    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    </style>

    <style name="AppTheme.NoStatusBar" parent="AppTheme.NoActionBar">
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowTranslucentNavigation">true</item>
        <item name="windowActionBarOverlay">true</item>
        <item name="android:windowActionBarOverlay">true</item>
    </style>
</resources>

还有styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

也许这里的关键是确保您使用 AppCompactActivity 以及使用 Theme.AppCompact 作为样式的根。

【讨论】:

【参考方案4】:

添加这个

android:fitsSystemWindows="true"

在 AppBarLayout 的内部视图中,它为我解决了这个问题

【讨论】:

谢谢。这里也一样..

以上是关于即使使用 windowTranslucentStatus 和 fitSystemWindows,CoordinatorLayout 也不会在状态栏后面绘制的主要内容,如果未能解决你的问题,请参考以下文章

即使我在 laravel 中使用 updateorcreate 方法,为啥还要复制数据

为啥即使使用 QThreadPool,GUI 也会冻结?

为啥 isConfiguration:compatibleWithStoreMetadata 会返回 yes,即使使用了映射模型?

为啥即使使用 Colab Pro 帐户也无法连接到 GPU 后端?

即使使用示例代码,mmenu 也无法正常工作

即使我使用 splitOn 参数后仍然出现异常