单击工具栏菜单时显示 NavigationBar
NavigationBar shows up when toolbar menu is clicked
您好,
我正在尝试让我的 android 应用全屏显示并隐藏导航栏。
它运行良好,但我注意到当我按下自定义工具栏上的按钮时,导航栏会重新出现并保持可见。它具有纯黑色,因此它不是从底部向上滑动时短暂显示的“正常”半透明版本等。
如何确保该栏保持隐藏状态?作为奖励问题,是否也可以隐藏临时半透明版本以便完全删除栏?
我在 activity 中使用以下代码隐藏 NavigationBar,并创建工具栏:
protected override void OnResume()
{
base.OnResume();
WindowCompat.SetDecorFitsSystemWindows(Window, false);
var windowInsetsControllerCompat = new WindowInsetsControllerCompat(Window, _MainContainer);
windowInsetsControllerCompat.Hide(WindowInsetsCompat.Type.SystemBars() | WindowInsetsCompat.Type.NavigationBars());
windowInsetsControllerCompat.SystemBarsBehavior = WindowInsetsControllerCompat.BehaviorShowTransientBarsBySwipe;
}
public override bool OnCreateOptionsMenu(IMenu menu)
{
MenuInflater.Inflate(Resource.Menu.custom_toolbar_menu, menu);
return true;
}
我的菜单是这样的:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/selectItem"
android:icon="@drawable/select_item_48"
android:title="@string/title_select_item"
app:showAsAction="always">
</item>
<item
android:id="@+id/moreVertical"
android:icon="@drawable/baseline_more_vert_black_48"
android:title="@string/more"
app:showAsAction="always">
<menu>
<item
android:id="@+id/logout"
android:title="@string/title_logout"/>
</menu>
</item>
</menu>
编辑
将我的代码移至 OnWindowFocusChanged 后效果更好,但在发生焦点更改时我仍然可以看到一个小的后退箭头。栏本身是完全透明的,应用程序仍然是全屏的,唯一的问题是由于某种原因后退箭头是可见的。
public override void OnWindowFocusChanged(bool hasFocus)
{
Log.Debug(Constants.TAG, $"SaleActivity OnWindowFocusChanged: {hasFocus}");
base.OnWindowFocusChanged(hasFocus);
WindowCompat.SetDecorFitsSystemWindows(Window, false);
var windowInsetsControllerCompat = new WindowInsetsControllerCompat(Window, Window.DecorView);
windowInsetsControllerCompat.Hide(WindowInsetsCompat.Type.SystemBars() | WindowInsetsCompat.Type.NavigationBars());
windowInsetsControllerCompat.SystemBarsBehavior = WindowInsetsControllerCompat.BehaviorShowTransientBarsBySwipe;
}
起初,我测试了菜单项,认为它被点击,系统会调用一些方法来显示导航栏。
所以你可以把下面的代码放到activity中,让导航条在焦点改变的时候消失。
public override void OnWindowFocusChanged(bool hasFocus)
{
base.OnWindowFocusChanged(hasFocus);
Window.SetFlags(WindowManagerFlags.Fullscreen, WindowManagerFlags.Fullscreen);
Window.DecorView.SystemUiVisibility = (StatusBarVisibility)
(SystemUiFlags.LowProfile
| SystemUiFlags.Fullscreen
| SystemUiFlags.HideNavigation
| SystemUiFlags.Immersive
| SystemUiFlags.ImmersiveSticky);
}
@Taxen0
你试过了吗?
windowInsetsControllerCompat.Hide(WindowInsetsCompat.Type.StatusBars() | WindowInsetsCompat.Type.NavigationBars());
当我第一次开始使用 windowInsetsController 时,就在他们首次发布 AndroidX.Core 之后 - 如果我没记错的话,它是 Android11,它始终为 null,因此我在 OnStart 中创建了一个。
我正在为片段执行以下操作,因此以下代码来自任何沉浸式片段都可以继承的基础 class。然后,使用OnResume和OnPause来控制隐藏和显示。
public override void OnStart()
{
windowInsetsControllerCompat = new WindowInsetsControllerCompat(Activity.Window, Activity.Window.DecorView);
if (Activity is MainActivity mainActivity)
{
mainActivity.SupportActionBar.Hide();
mainActivity.DisableDrawerLayout(); // Disable the navigationDrawer of the MainActivity. We don't want a user to be able to swipe it into view while viewing any of the gauges
}
base.OnStart();
}
public void HideSystemUi()
{
// 17/01/2021 Added this reference as an explanation of why we needed this code from Android 11 and on...
// Don't use android:fitsSystemWindows="true" anywhere.
// Refer to goto the bottom for this solution
WindowCompat.SetDecorFitsSystemWindows(Activity.Window, false);
//WindowInsetsControllerCompat windowInsetsControllerCompat = ViewCompat.GetWindowInsetsController(Activity.Window.DecorView); // Always null. Have to create our own
windowInsetsControllerCompat.Hide(WindowInsetsCompat.Type.StatusBars() | WindowInsetsCompat.Type.NavigationBars());
windowInsetsControllerCompat.SystemBarsBehavior = WindowInsetsControllerCompat.BehaviorShowTransientBarsBySwipe;
}
private void ShowSystemUi()
{
WindowCompat.SetDecorFitsSystemWindows(Activity.Window, true);
//WindowInsetsControllerCompat windowInsetsControllerCompat = ViewCompat.GetWindowInsetsController(Activity.Window.DecorView); // Always null. Have to create our own
windowInsetsControllerCompat.Show(WindowInsetsCompat.Type.StatusBars() | WindowInsetsCompat.Type.NavigationBars());
// 29/05/2021 This used to be before clearing the flags when we had them
if (Activity is MainActivity mainActivity)
{
mainActivity.SupportActionBar.Show();
mainActivity.EnableDrawerLayout();
}
}
无论您是使用手势还是 3 按钮导航栏,这都可以正常工作。
@Taxen0
你不想
windowInsetsControllerCompat.Hide(WindowInsetsCompat.Type.SystemBars() | WindowInsetsCompat.Type.NavigationBars());
你确实想要
windowInsetsControllerCompat.Hide(WindowInsetsCompat.Type.StatusBars() | WindowInsetsCompat.Type.NavigationBars());
证明给自己看 - 在调试器中,在上一行之后的行中中断并获取 WindowInsetsCompat.Type.SystemBars() | 的值WindowInsetsCompat.Type.NavigationBars() 在手表 window 中。你会发现它等于 7
现在同时检查WindowInsetsCompat.Type.StatusBars()的值| WindowInsetsCompat.Type.NavigationBars()。你会发现它等于 3
您的方式将隐藏两个栏,但是当您使用 BehaviorShowTransientBarsBySwipe
滑动时栏将再次隐藏时,NavigationBar 将保留,这可能不是您想要的,因为那样您的屏幕就不是完全身临其境。
您好,
我正在尝试让我的 android 应用全屏显示并隐藏导航栏。
它运行良好,但我注意到当我按下自定义工具栏上的按钮时,导航栏会重新出现并保持可见。它具有纯黑色,因此它不是从底部向上滑动时短暂显示的“正常”半透明版本等。
如何确保该栏保持隐藏状态?作为奖励问题,是否也可以隐藏临时半透明版本以便完全删除栏?
我在 activity 中使用以下代码隐藏 NavigationBar,并创建工具栏:
protected override void OnResume()
{
base.OnResume();
WindowCompat.SetDecorFitsSystemWindows(Window, false);
var windowInsetsControllerCompat = new WindowInsetsControllerCompat(Window, _MainContainer);
windowInsetsControllerCompat.Hide(WindowInsetsCompat.Type.SystemBars() | WindowInsetsCompat.Type.NavigationBars());
windowInsetsControllerCompat.SystemBarsBehavior = WindowInsetsControllerCompat.BehaviorShowTransientBarsBySwipe;
}
public override bool OnCreateOptionsMenu(IMenu menu)
{
MenuInflater.Inflate(Resource.Menu.custom_toolbar_menu, menu);
return true;
}
我的菜单是这样的:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/selectItem"
android:icon="@drawable/select_item_48"
android:title="@string/title_select_item"
app:showAsAction="always">
</item>
<item
android:id="@+id/moreVertical"
android:icon="@drawable/baseline_more_vert_black_48"
android:title="@string/more"
app:showAsAction="always">
<menu>
<item
android:id="@+id/logout"
android:title="@string/title_logout"/>
</menu>
</item>
</menu>
编辑
将我的代码移至 OnWindowFocusChanged 后效果更好,但在发生焦点更改时我仍然可以看到一个小的后退箭头。栏本身是完全透明的,应用程序仍然是全屏的,唯一的问题是由于某种原因后退箭头是可见的。
public override void OnWindowFocusChanged(bool hasFocus)
{
Log.Debug(Constants.TAG, $"SaleActivity OnWindowFocusChanged: {hasFocus}");
base.OnWindowFocusChanged(hasFocus);
WindowCompat.SetDecorFitsSystemWindows(Window, false);
var windowInsetsControllerCompat = new WindowInsetsControllerCompat(Window, Window.DecorView);
windowInsetsControllerCompat.Hide(WindowInsetsCompat.Type.SystemBars() | WindowInsetsCompat.Type.NavigationBars());
windowInsetsControllerCompat.SystemBarsBehavior = WindowInsetsControllerCompat.BehaviorShowTransientBarsBySwipe;
}
起初,我测试了菜单项,认为它被点击,系统会调用一些方法来显示导航栏。 所以你可以把下面的代码放到activity中,让导航条在焦点改变的时候消失。
public override void OnWindowFocusChanged(bool hasFocus)
{
base.OnWindowFocusChanged(hasFocus);
Window.SetFlags(WindowManagerFlags.Fullscreen, WindowManagerFlags.Fullscreen);
Window.DecorView.SystemUiVisibility = (StatusBarVisibility)
(SystemUiFlags.LowProfile
| SystemUiFlags.Fullscreen
| SystemUiFlags.HideNavigation
| SystemUiFlags.Immersive
| SystemUiFlags.ImmersiveSticky);
}
@Taxen0 你试过了吗?
windowInsetsControllerCompat.Hide(WindowInsetsCompat.Type.StatusBars() | WindowInsetsCompat.Type.NavigationBars());
当我第一次开始使用 windowInsetsController 时,就在他们首次发布 AndroidX.Core 之后 - 如果我没记错的话,它是 Android11,它始终为 null,因此我在 OnStart 中创建了一个。
我正在为片段执行以下操作,因此以下代码来自任何沉浸式片段都可以继承的基础 class。然后,使用OnResume和OnPause来控制隐藏和显示。
public override void OnStart()
{
windowInsetsControllerCompat = new WindowInsetsControllerCompat(Activity.Window, Activity.Window.DecorView);
if (Activity is MainActivity mainActivity)
{
mainActivity.SupportActionBar.Hide();
mainActivity.DisableDrawerLayout(); // Disable the navigationDrawer of the MainActivity. We don't want a user to be able to swipe it into view while viewing any of the gauges
}
base.OnStart();
}
public void HideSystemUi()
{
// 17/01/2021 Added this reference as an explanation of why we needed this code from Android 11 and on...
// Don't use android:fitsSystemWindows="true" anywhere.
// Refer to goto the bottom for this solution
WindowCompat.SetDecorFitsSystemWindows(Activity.Window, false);
//WindowInsetsControllerCompat windowInsetsControllerCompat = ViewCompat.GetWindowInsetsController(Activity.Window.DecorView); // Always null. Have to create our own
windowInsetsControllerCompat.Hide(WindowInsetsCompat.Type.StatusBars() | WindowInsetsCompat.Type.NavigationBars());
windowInsetsControllerCompat.SystemBarsBehavior = WindowInsetsControllerCompat.BehaviorShowTransientBarsBySwipe;
}
private void ShowSystemUi()
{
WindowCompat.SetDecorFitsSystemWindows(Activity.Window, true);
//WindowInsetsControllerCompat windowInsetsControllerCompat = ViewCompat.GetWindowInsetsController(Activity.Window.DecorView); // Always null. Have to create our own
windowInsetsControllerCompat.Show(WindowInsetsCompat.Type.StatusBars() | WindowInsetsCompat.Type.NavigationBars());
// 29/05/2021 This used to be before clearing the flags when we had them
if (Activity is MainActivity mainActivity)
{
mainActivity.SupportActionBar.Show();
mainActivity.EnableDrawerLayout();
}
}
无论您是使用手势还是 3 按钮导航栏,这都可以正常工作。
@Taxen0
你不想
windowInsetsControllerCompat.Hide(WindowInsetsCompat.Type.SystemBars() | WindowInsetsCompat.Type.NavigationBars());
你确实想要
windowInsetsControllerCompat.Hide(WindowInsetsCompat.Type.StatusBars() | WindowInsetsCompat.Type.NavigationBars());
证明给自己看 - 在调试器中,在上一行之后的行中中断并获取 WindowInsetsCompat.Type.SystemBars() | 的值WindowInsetsCompat.Type.NavigationBars() 在手表 window 中。你会发现它等于 7
现在同时检查WindowInsetsCompat.Type.StatusBars()的值| WindowInsetsCompat.Type.NavigationBars()。你会发现它等于 3
您的方式将隐藏两个栏,但是当您使用 BehaviorShowTransientBarsBySwipe
滑动时栏将再次隐藏时,NavigationBar 将保留,这可能不是您想要的,因为那样您的屏幕就不是完全身临其境。