半透明/透明状态栏+ CoordinatorLayout +工具栏+片段

我有以下设置:

  • 我正在使用AppCompat
  • MainActivity,包含一个片段并有一个工具栏,在向下滚动时隐藏
  • FragmentRecyclerView
  • 所有适合屏幕的视图都在xml布局中具有相应的android:fitsSystemWindows="true"

问题是,在这种情况下我无法使状态栏透明。 我所做的是:

  1. 创建活动并调用setContent
  2. 然后我尝试调整活动以编程方式获得如下的半透明工具栏:

     @TargetApi(Build.VERSION_CODES.LOLLIPOP) public void themeNavAndStatusBar(Activity activity) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return; Window w = activity.getWindow(); w.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); w.setFlags( WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); w.setFlags( WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); w.setNavigationBarColor(activity.getResources().getColor(android.R.color.transparent)); w.setStatusBarColor(activity.getResources().getColor(android.R.color.transparent)); } 
  3. 用片段替换活动( @+id/frame_container )中的占位符

在这种情况下,状态栏是纯色的,并且未在其下方绘制视图…为什么?

我想要的是

我想要一个工具栏,它滚动屏幕并完全隐藏,而此工具栏下面的内容应该适合屏幕,并在透明导航栏后面绘制。

布局

这是我的主要活动:

                  

这是我的片段,将放在主要活动中:

       

编辑 – 截图

我使用浅色/深色基本主题并手工制作主题(因为用户可以选择任何颜色作为主要/强调颜色),所以不要介意工具栏是白色的(它是默认的主题背景颜色和原色)。 我还添加了一个黑色边框,以便您看到活动结束的地方……

  • 第一个屏幕截图:显示工具栏,没有滚动任何内容
  • 第二个屏幕截图:我刚刚开始滚动=>工具栏现在应该滚动
  • 第三个屏幕截图:主要内容现在应滚动到导航栏下方…

最后,我当然会让工具栏和导航栏半透明,以获得更好的视觉效果……

在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

Solutions Collecting From Web of "半透明/透明状态栏+ CoordinatorLayout +工具栏+片段"

tl; drandroid:fitsSystemWindows="false"至少设置为根CoordinatorLayout和内部片段容器@frame_container

这可能不是最终的解决方案(即可能有其他fitsSystemWindows要更改)所以告诉我你是否有任何问题。

为什么

说到状态栏,我认为fitsSystemWindows是这样的:

  • fitsSystemWindows="false" :由于您设置了窗口标记,因此状态栏正常绘制视图。
  • fitsSystemWindows="true" :由于您设置的窗口标记, 状态栏正常绘制视图,但添加了一个顶部填充,以便在状态栏下方绘制内容并且它们不重叠。

事实上,在我看来,你看到的白色不是状态栏颜色,而是你的CoordinatorLayout背景。 这是由于协调器上的fitsSystemWindows="true" :它将背景绘制到整个窗口,但是向内容添加了顶部填充,因此状态栏不会覆盖内部视图。

这不是你想要的。 您的内部内容必须由状态栏覆盖,因此您必须将fitsSystemWindows="false"设置为协调器(因此它不会应用顶部填充),并且可能设置为内容本身。

一旦了解了它的工作原理, 就可以轻松调试并实现您所需的效果实际上,事实并非如此。 多年过去了,但我仍然花费数小时试图找出正确的fitsSystemWindows组合,因为大多数视图(至少在支持库中)都会覆盖我上面提到的默认行为,其方式大多不直观。 有关如何使用它的小指南,请参阅此文章 。

编辑styles.xml(v21),添加以下样式

   

您可以根据自己的喜好更改父主题,但现在在AndroidManifest.xml文件中为特定活动声明此主题,如下所示:

   

这将使您的内容在透明操作栏下可见。

现在使用以下内容将您的工具栏正确对齐StatusBar,在您的oncreate中调用它:

  toolbar.setPadding(0, getStatusBarHeight(), 0, 0); 

使用以下方法获取状态栏高度:

 public int getStatusBarHeight() { int result = 0; int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { result = getResources().getDimensionPixelSize(resourceId); } return result; } 

从协调器布局标记中删除以下内容:

  android:fitsSystemWindows="true" 

现在,为了折叠工具栏或隐藏它,您可以参考以下教程:

 http://antonioleiva.com/collapsing-toolbar-layout/ 

确保您使用的是以下版本的设计支持库,因为它没有错误:

  compile 'com.android.support:design:23.1.0' 

在阅读了您对问题的描述后,我认为Google相册的样式符合您的要求。

好的,您的问题只有一些提示。 经过我的测试,它确实有效。

  • 如果要在状态栏后面显示内容,当Android版本级别大于19(即KitKat )时,需要将true到您的样式中
  • 如果要在导航栏后面显示内容,当Android版本级别大于19(即KitKat )时,需要将true到您的样式中
  • 如果要在内容向上滚动时平滑地隐藏Toolbar并在内容向下滚动时平滑显示Toolbar ,则需要根据当前代码将app:layout_collapseMode="parallax"Toolbar的属性中。当然,你需要使用CollapsingToolbarLayout CoordinatorLayoutAppBarLayout协调Toolbar

对我来说,原因不是它本身不起作用,而是我使用Mike Penz的材料抽屉库,这个库确实使用工具栏后面的全屏+偏移+自定义背景,所以我必须解决这个特殊的问题建立…

我会奖励那些在我看来最具信息性的答案的点数……

我有同样的问题,我的解决方案是添加android:fitsSystemWindows =“true”DrawerLayout

  ....  

我有相关问题取决于android:fitsSystemWindows设置。 错误:在导航栏下绘制小吃一旦为真:状态栏没有透明背景

解决方案非常简单……只需要添加android:layout_marginBottom =“48dp”。 这样的CoordinatorLayout:

 just to add  

理论上导航栏应该具有固定大小“48dp”,但在将来的版本中它可能会发生变化(比如状态栏在棉花糖中变得更薄1dp),所以我不会依赖于固定大小。 更好的是另外得到它并在运行时应用。

如果您正在使用像我这样的Google地图您可能想知道ActionBar /工具栏大小和运行时的导航栏:

在onCreate中使用此代码:

  final TypedArray styledAttributes = MapsActivity.this.getTheme().obtainStyledAttributes( new int[]{android.R.attr.actionBarSize}); mToolbarHeight = (int) styledAttributes.getDimension(0, 0); styledAttributes.recycle(); // translucent bars code. Will not fire below Lollipop // Ask NavigationBar Height ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.coordinatorLayout), new OnApplyWindowInsetsListener() { // setContentView() must be fired already @Override public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) { statusBar = insets.getSystemWindowInsetTop(); // You may also need this value mNavBarHeight = insets.getSystemWindowInsetBottom(); if (mMap != null) mMap.setPadding(0, mToolbarHeight, 0, mNavBarHeight); // else will be set in onMapReady() SharedPreferences.Editor editor = mSharedPref.edit(); editor .putInt(NAVBAR_HEIGHT_KEY, mNavBarHeight) .commit(); // Save the results in flash memory and run the code just once on app first run instead of doing it every run return insets; } } ); 

什么是重要的。 如果您有一些额外的图层,如抽屉等,则将它们封装在内部而不是外部的CoordinatorLayout中,否则它将通过marginBottom使其他视图更短

正如一些用户所说,通过设置android:fitsSystemWindows="false" ,布局重叠statusbar下方。

我通过设置android:fitsSystemWindows="true"并在CoordinatorLayout标签设置app:statusBarBackground="@android:color/transparent"解决了它app:statusBarBackground="@android:color/transparent"