关闭 Contex 操作模式时黑色状态栏不会消失
Black status bar doesn't disappear when closing Contex Action Mode
为了能够使抽屉布局位于状态栏下方,我需要将其颜色设置为透明并将 SystemUIVisibility
设置为全屏。启动上下文操作模式时,状态栏变为黑色。
这可以 "solved" 通过在 OnCreateActionMode
中设置状态栏的颜色并在 OnDestroyActionMode
中再次使其透明(尽管您仍然可以看到黑色的条片刻)。
真正的问题出现在我处于上下文操作模式时,我导航到另一个片段,在导航之前完成上下文模式。这使得黑色视图出现在片段的布局上并且无法删除。
您可以看到此行为的图像:
.
我正在使用 Xamarin Android,但 java 中的实现应该非常相似。抽屉布局和主要内容都是以编程方式创建的:
设置状态栏:
if (Build.VERSION.SdkInt > BuildVersionCodes.Lollipop)
{
//we don't need the translucent flag this is handled by the theme
StatusBarHelper.SetTranslucentStatusFlag(Activity, false);
//set the statusbarcolor transparent to remove the black shadow
StatusBarHelper.SetStatusBarColor(Activity, Color.Transparent);
}
StatusBarHelper.SetLightStatusBar(Activity, false);`
创建主视图(带抽屉):
_drawerLayout = new DrawerLayout(inflater.Context)
{
LayoutParameters = new DrawerLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent),
};
ViewCompat.SetOnApplyWindowInsetsListener(_drawerLayout, this); // This only works from lollipop
using (FrameLayout contentContainer = new FrameLayout(inflater.Context))
{
contentContainer.LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent);
// Sets fullscreen to be able to go under the status bar
if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
{
// Already works since Kitkat, but since SetOnApplyWindowInsets only works from lollipop, for the moment we enable this later
contentContainer.SystemUiVisibility = (StatusBarVisibility)(SystemUiFlags.LayoutStable | SystemUiFlags.LayoutFullscreen | SystemUiFlags.LayoutHideNavigation);
}
// Make the content ViewGroup ignore insets so that it does not use the default padding
ViewCompat.SetOnApplyWindowInsetsListener(contentContainer, this);
// Scrim view. This is used to paint under the status bar the color that we want
using (View statusBarScrim = new View(inflater.Context))
{
statusBarScrim.Id = Resource.Id.scrim_view;
statusBarScrim.LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, 0);
statusBarScrim.SetBackgroundColor(new Color(ResourcesCompat.GetColor(Resources, Resource.Color.primaryDark, null)));
ViewCompat.SetOnApplyWindowInsetsListener(statusBarScrim, this);
contentContainer.AddView(statusBarScrim);
}
//Create main content (toolbar and fragment container)
using (var mainContent = CreateMainContent(inflater))
{
contentContainer.AddView(mainContent);
}
contentContainer.SetFitsSystemWindows(true);
_drawerLayout.AddView(contentContainer);
}
最后是 insetListener 的代码:
// This is used to handle the scrim view
// The scrim view is used to cover the status bar with a color
// The scrim consumes the top inset by getting its height
// All other views are ignored
public WindowInsetsCompat OnApplyWindowInsets(View v, WindowInsetsCompat insets)
{
// Check if it's the scrim view
// If it's not the scrim it will not consume the insets
if (v.Id == Resource.Id.scrim_view)
{
var topInset = insets.SystemWindowInsetTop;
if (v.LayoutParameters.Height != topInset)
{
v.LayoutParameters.Height = topInset;
v.RequestLayout();
}
}
return insets;
}
要创建上下文操作菜单,我使用 StartSupportActionMode
,在 OnCreateActionMode
中,我只是设置菜单。状态栏变成黑色(上下文操作模式添加了一个像我正在使用的稀松布一样的视图,但我还没有找到给它着色的方法)。
此菜单中有一个项目可以导航到您在我之前附加的图像中看到的屏幕。当按下这个项目时,我调用 _actionMode.Finish()
然后导航到那里。结果是上下文操作模式工具栏消失了,但这个黑色稀松布视图没有。
如果我在导航之前添加延迟,则不会发生此错误,所以我认为它与动画有关?无论哪种方式,延迟解决问题总是不好的做法,因为每个设备都会有所不同。
好的,所以我很确定这一定是 AppCompat 的 ActionMode 的错误。最后,我很幸运,在导航到的片段上设置 FitSystemWindows 似乎解决了这个问题。
另外,我找到了如何设置动作模式添加的稀松布布局的颜色,而不会看到黑条。
我在这里找到了答案 所以所有的功劳都归功于他。无论哪种方式,我都会将其粘贴在这里:
<color name="abc_input_method_navigation_guard" tools:override="true">@color/primary_dark</color>
为了能够使抽屉布局位于状态栏下方,我需要将其颜色设置为透明并将 SystemUIVisibility
设置为全屏。启动上下文操作模式时,状态栏变为黑色。
这可以 "solved" 通过在 OnCreateActionMode
中设置状态栏的颜色并在 OnDestroyActionMode
中再次使其透明(尽管您仍然可以看到黑色的条片刻)。
真正的问题出现在我处于上下文操作模式时,我导航到另一个片段,在导航之前完成上下文模式。这使得黑色视图出现在片段的布局上并且无法删除。
您可以看到此行为的图像:
我正在使用 Xamarin Android,但 java 中的实现应该非常相似。抽屉布局和主要内容都是以编程方式创建的:
设置状态栏:
if (Build.VERSION.SdkInt > BuildVersionCodes.Lollipop)
{
//we don't need the translucent flag this is handled by the theme
StatusBarHelper.SetTranslucentStatusFlag(Activity, false);
//set the statusbarcolor transparent to remove the black shadow
StatusBarHelper.SetStatusBarColor(Activity, Color.Transparent);
}
StatusBarHelper.SetLightStatusBar(Activity, false);`
创建主视图(带抽屉):
_drawerLayout = new DrawerLayout(inflater.Context)
{
LayoutParameters = new DrawerLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent),
};
ViewCompat.SetOnApplyWindowInsetsListener(_drawerLayout, this); // This only works from lollipop
using (FrameLayout contentContainer = new FrameLayout(inflater.Context))
{
contentContainer.LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent);
// Sets fullscreen to be able to go under the status bar
if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
{
// Already works since Kitkat, but since SetOnApplyWindowInsets only works from lollipop, for the moment we enable this later
contentContainer.SystemUiVisibility = (StatusBarVisibility)(SystemUiFlags.LayoutStable | SystemUiFlags.LayoutFullscreen | SystemUiFlags.LayoutHideNavigation);
}
// Make the content ViewGroup ignore insets so that it does not use the default padding
ViewCompat.SetOnApplyWindowInsetsListener(contentContainer, this);
// Scrim view. This is used to paint under the status bar the color that we want
using (View statusBarScrim = new View(inflater.Context))
{
statusBarScrim.Id = Resource.Id.scrim_view;
statusBarScrim.LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, 0);
statusBarScrim.SetBackgroundColor(new Color(ResourcesCompat.GetColor(Resources, Resource.Color.primaryDark, null)));
ViewCompat.SetOnApplyWindowInsetsListener(statusBarScrim, this);
contentContainer.AddView(statusBarScrim);
}
//Create main content (toolbar and fragment container)
using (var mainContent = CreateMainContent(inflater))
{
contentContainer.AddView(mainContent);
}
contentContainer.SetFitsSystemWindows(true);
_drawerLayout.AddView(contentContainer);
}
最后是 insetListener 的代码:
// This is used to handle the scrim view
// The scrim view is used to cover the status bar with a color
// The scrim consumes the top inset by getting its height
// All other views are ignored
public WindowInsetsCompat OnApplyWindowInsets(View v, WindowInsetsCompat insets)
{
// Check if it's the scrim view
// If it's not the scrim it will not consume the insets
if (v.Id == Resource.Id.scrim_view)
{
var topInset = insets.SystemWindowInsetTop;
if (v.LayoutParameters.Height != topInset)
{
v.LayoutParameters.Height = topInset;
v.RequestLayout();
}
}
return insets;
}
要创建上下文操作菜单,我使用 StartSupportActionMode
,在 OnCreateActionMode
中,我只是设置菜单。状态栏变成黑色(上下文操作模式添加了一个像我正在使用的稀松布一样的视图,但我还没有找到给它着色的方法)。
此菜单中有一个项目可以导航到您在我之前附加的图像中看到的屏幕。当按下这个项目时,我调用 _actionMode.Finish()
然后导航到那里。结果是上下文操作模式工具栏消失了,但这个黑色稀松布视图没有。
如果我在导航之前添加延迟,则不会发生此错误,所以我认为它与动画有关?无论哪种方式,延迟解决问题总是不好的做法,因为每个设备都会有所不同。
好的,所以我很确定这一定是 AppCompat 的 ActionMode 的错误。最后,我很幸运,在导航到的片段上设置 FitSystemWindows 似乎解决了这个问题。
另外,我找到了如何设置动作模式添加的稀松布布局的颜色,而不会看到黑条。
我在这里找到了答案
<color name="abc_input_method_navigation_guard" tools:override="true">@color/primary_dark</color>