棒棒糖:在颜色设置为透明的状态下绘制statusBar

我已经设置我的statusBar颜色为透明的棒棒糖只有在我的主题中的以下行:

<item name="android:statusBarColor">@android:color/transparent</item> 

现在我需要在它背后画,但是我不能在它背后画任何东西。 我知道如何使用windowTranslucentStatus属性来做到这windowTranslucentStatus ,但不想使用这个属性,因为它会忽略设置为透明状态的statusBar的颜色。

方法#1:

要实现完全透明的状态栏,您必须使用statusBarColor ,该API仅在API 21及更高版本上可用。 windowTranslucentStatus在API 19及更高windowTranslucentStatus中可用,但为状态栏添加了浅色背景。 但是,设置windowTranslucentStatus确实可以实现将statusBarColor更改为transparent的一件事:它设置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); 

请务必在/res/values-v21/styles.xml中设置透明度:

 <item name="android:statusBarColor">@android:color/transparent</item> 

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

 getWindow().setStatusBarColor(Color.TRANSPARENT); 

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

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

方法2:

如果您只需要在状态栏下绘制背景图片,而不是将视图放置在背后,可以通过简单地将活动主题的背景设置为所需的图像并设置状态栏透明度来完成,如方法# 1。 这是我几个月前为Android Police文章创build截图的方法。

方法#3:

如果你不得不忽略某些布局的标准系统插件,而让它们在其他布局中工作,唯一可行的方法是使用经常链接的ScrimInsetsFrameLayout类。 当然,在这个课堂上所做的一些事情并不是所有情况都需要的。 例如,如果您不打算使用合成状态栏覆盖,只需在init()方法中注释掉所有内容,不要在attrs.xml文件中添加任何内容。 我已经看到了这种方法的工作原理,但是我认为你会发现它带来了一些其他的影响,可能会有很多工作要解决。

我也看到你反对包装多个布局。 在将一个布局封装在另一个布局的情况下,其中两个布局的高度和宽度都是match_parent ,所以性能影响太小,不值得担心。 无论如何,你可以通过改变它从FrameLayout扩展到任何其他types的布局类,你可以完全避免这种情况。 它会工作得很好。

这对我来说是完美的


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

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

试试这个主题

 <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> 

请确定,您的布局设置

 android:fitsSystemWindows="false" 

代替

 <item name="android:statusBarColor">@android:color/transparent</item> 

使用以下内容:

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

并确保在“MainActivity”布局中删除顶部填充(默认添加)。

请注意,这不会使状态栏完全透明,并且在状态栏上仍然会有一个“淡黑色”覆盖。

来自Cody Toombs的解决scheme几乎为我做了诀窍。 我不确定这是否与Xamarin有关,但我现在有一个可以接受的解决scheme:

例

这是我的设置:

我有一个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> 

值-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> 

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> 

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

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

注意,我设置了DrawsSystemBarBackgrounds标志,这使得所有的区别

 Window.AddFlags (WindowManagerFlags.DrawsSystemBarBackgrounds); 

事实上,我花了很多时间,事实上太多了。 希望这个答案有助于任何人尝试实现相同的事情。

你可以使用ScrimInsetFrameLayout

https://github.com/google/iosched/blob/master/android/src/main/java/com/google/samples/apps/iosched/ui/widget/ScrimInsetsFrameLayout.java

android:fitsSystemWindows =“true”应该在scrim布局上设置!

类似于发布的一些解决scheme,但在我的情况下,我做了状态栏透明,并修复了一些负边限的行动栏的位置

 if (Build.VERSION.SDK_INT >= 21) { getWindow().setStatusBarColor(Color.TRANSPARENT); FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) toolbar.getLayoutParams(); lp.setMargins(0, -getStatusBarHeight(), 0, 0); } 

我在工具栏和根视图中使用

 android:fitsSystemWindows="true" 

我有同样的问题,所以我创build的ImageView后面的状态栏API 19+绘制

在状态栏gist.github.com后面设置自定义图像

 public static void setTransparent(Activity activity, int imageRes) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { return; } // set flags if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); activity.getWindow().setStatusBarColor(Color.TRANSPARENT); } else { activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); } // get root content of system window //ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0); // rootView.setFitsSystemWindows(true); // rootView.setClipToPadding(true); ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content); if (contentView.getChildCount() > 1) { contentView.removeViewAt(1); } // get status bar height int res = activity.getResources().getIdentifier("status_bar_height", "dimen", "android"); int height = 0; if (res != 0) height = activity.getResources().getDimensionPixelSize(res); // create new imageview and set resource id ImageView image = new ImageView(activity); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, height); image.setLayoutParams(params); image.setImageResource(imageRes); image.setScaleType(ScaleType.MATRIX); // add image view to content view contentView.addView(image); // rootView.setFitsSystemWindows(true); } 

使用Android Studio 1.4,带有锅炉板代码的模板项目将在AppbarLayout和/或工具栏上设置Overlay主题。 它们也被设置为通过fitSystemWindow属性= true呈现在状态栏的后面。 这将导致只有工具栏被直接渲染到状态栏的下面,其他的东西都会在工具栏下面呈现。 所以上面提供的解决scheme不能自行工作。 您将不得不做出以下更改。

  • 删除叠加主题或将其更改为工具栏的非叠加主题。
  • 将下面的代码放入styles-21.xml文件中。

    @android:彩色/透明

  • 将此主题分配给AndroidManifest.xml文件中包含导航抽屉的活动。

这将使导航抽屉在透明状态栏后面呈现。

这是我用来完成这个的主题:

 <style name="AppTheme" parent="@android:style/Theme.NoTitleBar"> <!-- Default Background Screen --> <item name="android:background">@color/default_blue</item> <item name="android:windowTranslucentStatus">true</item> </style> 

正确的解决scheme是将您的Activity标签下的XML属性更改为低于样式。 它只是工作

  android:theme="@style/Theme.AppCompat.Light.NoActionBar"