Чтобы иметь возможность сделать макет ящика go под строкой состояния, мне нужно было установить его прозрачный цвет и установить SystemUIVisibility
в полноэкранный режим. При запуске Context Action Mode строка состояния становится черной.
Эту проблему можно «решить», установив цвет строки состояния в 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 исчезает, но это черное сетчатое представление не отображается.
Если я добавлю задержку до перехода, эта ошибка не произойдет, поэтому я думаю, что она как-то связана с анимация? В любом случае, решение проблем с задержкой всегда является плохой практикой, потому что это будет отличаться в каждом устройстве.