即使使用 windowTranslucentStatus 和 fitsSystemWindows,CoordinatorLayout 也不会在状态栏后面绘制
CoordinatorLayout not drawing behind status bar even with windowTranslucentStatus and fitsSystemWindows
我正在尝试像这样在状态栏后面绘制视图:
我尝试使用推荐的技术来产生这种效果,但我得到了这个:
从屏幕截图中可以清楚地看出,我的应用内容 none 被绘制在状态栏后面。
有趣的是,Nav Drawer 设法在状态栏后面绘制:
我做过的事情:
- 使用支持库小部件 -
CoordinatorLayout
、AppBarLayout
、Toolbar
、DrawerLayout
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>
这是我的 activity 布局:
<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>
我的 activity 布局中的 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>
为未来的读者编辑:关于主题和问题的评论有很多很好的信息,请务必通读。
原答案:
你的主题是错误的,这就是原因。
不幸的是,在 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);
}
然后你可以从你的activitysetTranslucentStatusBar(getWindow());
打电话
编辑:
在 Android.
中,使状态栏半透明并在其后面绘制(出于某种原因我无法理解)是两个独立的任务
我仔细查看了我的代码,我确信我的布局 android:fitsSystemWindows="true"
比 CoordinatorLayout
.
多很多
下面是我的布局中带有 android:fitsSystemWindows="true"
的所有视图:
- 协调器布局
- AppBarLayout
- CollapsingToolbarLayout
- ImageView(带背景图片)
- FrameLayout(带表头内容)
所以我的建议是 test/try 在你的 XML 上填满 android:fitsSystemWindows="true"
。
这真的让我感到困惑,但我最终通过我的观点组合找到了答案,如下所示:
<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);
}
- 如果我想在StatusBar后面绘制我使用CoordinatorLayout作为[=35= Activity 的最父视图 (android:fitsSystemWindows="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 作为样式的根。
添加这个
android:fitsSystemWindows="true"
在 AppBarLayout 的内部视图中,它解决了我的问题
我正在尝试像这样在状态栏后面绘制视图:
我尝试使用推荐的技术来产生这种效果,但我得到了这个:
从屏幕截图中可以清楚地看出,我的应用内容 none 被绘制在状态栏后面。
有趣的是,Nav Drawer 设法在状态栏后面绘制:
我做过的事情:
- 使用支持库小部件 -
CoordinatorLayout
、AppBarLayout
、Toolbar
、DrawerLayout
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>
这是我的 activity 布局:
<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>
我的 activity 布局中的 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>
为未来的读者编辑:关于主题和问题的评论有很多很好的信息,请务必通读。
原答案:
你的主题是错误的,这就是原因。
不幸的是,在 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);
}
然后你可以从你的activitysetTranslucentStatusBar(getWindow());
编辑:
在 Android.
中,使状态栏半透明并在其后面绘制(出于某种原因我无法理解)是两个独立的任务我仔细查看了我的代码,我确信我的布局 android:fitsSystemWindows="true"
比 CoordinatorLayout
.
下面是我的布局中带有 android:fitsSystemWindows="true"
的所有视图:
- 协调器布局
- AppBarLayout
- CollapsingToolbarLayout
- ImageView(带背景图片)
- FrameLayout(带表头内容)
所以我的建议是 test/try 在你的 XML 上填满 android:fitsSystemWindows="true"
。
这真的让我感到困惑,但我最终通过我的观点组合找到了答案,如下所示:
<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);
}
- 如果我想在StatusBar后面绘制我使用CoordinatorLayout作为[=35= Activity 的最父视图 (android:fitsSystemWindows="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 作为样式的根。
添加这个
android:fitsSystemWindows="true"
在 AppBarLayout 的内部视图中,它解决了我的问题