c# - 在 Android、Xamarin.forms 上的整个应用程序中保持沉浸式模式
问题描述
我想使用 Xamarin.forms 在 Android 上的整个应用程序中保持沉浸式模式。我读过一些博客和帖子。这个有效,但只有在我按下输入文本框或滚动屏幕之前。我想避免这种情况。这个问题辩论了我的担忧,但我不明白解决方案。也许它已经过时了。我的 android 设备是 7.1,这是我在.Android
MainActivity
, void OnCreate
,上的代码void OnCreate
:
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity{
protected override void OnCreate(Bundle savedInstanceState){
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
LoadApplication(new App());
ImmersiveMode();
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults){
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
public void ImmersiveMode() {
int uiOptions = (int)(Forms.Context as Activity).Window.DecorView.SystemUiVisibility;
uiOptions |= (int)SystemUiFlags.Fullscreen;
uiOptions |= (int)SystemUiFlags.HideNavigation;
uiOptions |= (int)SystemUiFlags.ImmersiveSticky;
(Forms.Context as Activity).Window.DecorView.SystemUiVisibility = (StatusBarVisibility)uiOptions;
}
}
我该如何解决这个问题?您能否具体说明我应该在哪里找到新代码。我是 Xamarin.Forms 的菜鸟,对我来说看起来很棘手。谢谢
编辑:这段代码:
this.Window.AddFlags(WindowManagerFlags.Fullscreen);
上.Android
MainActivity
隐藏带有 wifi 信号、时间、蓝牙等的 Android 栏。
有没有这样一行来隐藏这个android按钮?
解决方案
Window.DecorView.SystemUiVisibility
自 起已弃用Android R (11)
。在这个 API 版本中有一种新的方法可以做到这一点。
下面是我在我的一个应用程序中使用的代码。我不得不重写 MainActivity 类中的一堆方法。
using System;
using Android.App;
using Android.Content.PM;
using Android.Runtime;
using Android.OS;
using Android.Views;
namespace SampleApp.Droid
{
[Activity(Label = "SampleApp", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize )]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
SetFullscreenFlags();
}
protected override void OnResume()
{
base.OnResume();
SetFullscreenFlags();
}
public override void OnWindowFocusChanged(bool hasFocus)
{
base.OnWindowFocusChanged(hasFocus);
SetFullscreenFlags();
}
protected void SetFullscreenFlags()
{
var attrs = Window.Attributes;
attrs.Flags |= WindowManagerFlags.Fullscreen;
Window.Attributes = attrs;
// BuildVersionCodes has a wrong value for Android R (1000 instead of 30)
// https://github.com/xamarin/xamarin-android/issues/5723
// if (Build.VERSION.SdkInt >= BuildVersionCodes.R)
if ((int)Build.VERSION.SdkInt >= 30)
{
Window.SetDecorFitsSystemWindows(false);
if (Window.InsetsController != null)
{
Window.InsetsController.Hide(WindowInsets.Type.NavigationBars());
Window.InsetsController.Hide(WindowInsets.Type.StatusBars());
Window.InsetsController.Hide(WindowInsets.Type.SystemBars());
Window.InsetsController.Show(WindowInsets.Type.Ime());
}
}
else
{
var uiOptions = (int)Window.DecorView.SystemUiVisibility;
var newUiOptions = (int)uiOptions;
newUiOptions |=
(int)SystemUiFlags.LayoutStable |
(int)SystemUiFlags.LayoutHideNavigation |
(int)SystemUiFlags.LayoutFullscreen |
(int)SystemUiFlags.HideNavigation |
(int)SystemUiFlags.Fullscreen |
(int)SystemUiFlags.ImmersiveSticky;
Window.DecorView.SystemUiVisibility = (StatusBarVisibility)newUiOptions;
}
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
之前,我也实现了View.IOnSystemUiVisibilityChangeListener
接口。但它也已被弃用,并将在未来的版本中删除:
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity, View.IOnSystemUiVisibilityChangeListener
{
protected override void OnCreate(Bundle savedInstanceState)
{
// omitted code
Window.DecorView.SetOnSystemUiVisibilityChangeListener(this);
}
public void OnSystemUiVisibilityChange([GeneratedEnum] StatusBarVisibility visibility)
{
SetFullscreenFlags();
}
}
编辑:
如果您想在用户将某些输入控件聚焦在您的屏幕上后保持沉浸式模式,您可以实现ViewTreeObserver.IOnGlobalFocusChangeListener
界面。这是我的做法:
public class MainActivity :
global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity,
ViewTreeObserver.IOnGlobalFocusChangeListener
{
protected override void OnCreate(Bundle savedInstanceState)
{
// ommited code
}
public override void SetContentView(View view)
{
base.SetContentView(view);
if (view?.ViewTreeObserver != null)
view.ViewTreeObserver.AddOnGlobalFocusChangeListener(this);
}
public override void SetContentView(View view, ViewGroup.LayoutParams @params)
{
base.SetContentView(view, @params);
if (view?.ViewTreeObserver != null)
view.ViewTreeObserver.AddOnGlobalFocusChangeListener(this);
}
public void OnGlobalFocusChanged(View oldFocus, View newFocus)
{
SetFullscreenFlags();
}
}
推荐阅读
- scala - 如何使用类型参数扩展案例类?
- javascript - 获取div的id
- keycloak - Keycloak - how to implement delegated administration
- c++ - When looping through all processes, the process name stays the same but the process ID changes
- android - 如何使 TextView 在具有更高屏幕比例的设备上响应?
- php - How to separate html for header/footer?
- python - Scipy.Optimize.Curve_Fit Not Fitting Cos^2 Well
- typescript - haskell 等效于 typescript 映射函数
- reactjs - How to show the article details , i m facing problem
- r - rootsolve::multiroot 函数对角元素为零问题