CoordinatorLayout即使使用windowTranslucentStatus和fitsSystemWindows

时间:2015-11-12 09:57:29

标签: android material-design android-support-library statusbar android-coordinatorlayout

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

我尝试用推荐的技术产生这种效果,但我得到了这个:

Actual result

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

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

enter image description here

我做的东西:

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

这是我的应用主题:

<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_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <FrameLayout android:id="@+id/page_container"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
                 android:fitsSystemWindows="true"/>

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        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_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".MainActivity">

    <FrameLayout android:layout_width="match_parent"
                 android:layout_height="match_parent"
                 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_width="wrap_content"
                  android:layout_height="wrap_content" />
    </FrameLayout>

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

        <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: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_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        android:src="@android:drawable/ic_dialog_email" />

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

4 个答案:

答案 0 :(得分:27)

为未来的读者编辑:有很多关于这个主题和评论问题的好信息,请务必仔细阅读。

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

从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);
   }

然后您可以通过您的活动setTranslucentStatusBar(getWindow());

致电

修改

使状态栏保持半透明状态(由于某些原因我无法理解)是Android中的两个独立任务。

我对我的代码进行了更多查看,而且我的布局确实比android:fitsSystemWindows="true"多了CoordinatorLayout

下面的

是关于我的布局的所有视图,其中包含android:fitsSystemWindows="true"

  • CoordinatorLayout
  • AppBarLayout
  • CollapsingToolbarLayout
  • ImageView(带背景图片)
  • FrameLayout(包含标题的内容)

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

答案 1 :(得分:0)

这对我来说真的很混乱,但我最终想出了我的观点组合,看起来像这样:

<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);
   }

答案 2 :(得分:0)

  1. 如果我想在 StatusBar 后面绘制,我使用 CoordinatorLayout 作为最常见的父视图(android: fitsSystemWindows = “假”)
  2. 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));
            }
    
    1. 如果我希望 StatusBar 能够转换并且同步远离隐藏在StatusBar后面的视图我使用带有参数的大多数父视图FrameLayout

    2. 我的 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 用作样式的root。

答案 3 :(得分:0)

添加此

android:fitsSystemWindows="true"

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