【发布时间】:2020-01-29 15:00:24
【问题描述】:
为了能够使抽屉布局位于状态栏下方,我需要将其颜色设置为透明并将SystemUIVisibility 设置为全屏。启动上下文操作模式时,状态栏变为黑色。
这可以通过在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(),然后导航到那里。结果是 Context Action Mode 工具栏消失了,但是这个黑色的 scrim 视图没有。
如果我在导航之前添加延迟不会发生此错误,所以我认为它与动画有关?无论哪种方式,延迟解决问题总是不好的做法,因为每个设备都会有所不同。
【问题讨论】:
-
您好,感谢您的回复,但这并不能回答我的问题,因为它解释了如何设置状态栏颜色及其项目的颜色。我的问题是动作模式回调完成,但它创建的黑色视图在导航到另一个片段时不会消失
-
对不起,上次我检查了屏幕截图在那里。在这种情况下,也粘贴您的 xml 布局代码
-
没问题,我现在已经添加了我正在使用的代码。谢谢!
标签: android navigation-drawer drawerlayout android-statusbar contextual-action-bar