在 android 上防止通过 xamarin 表单中的硬件后退按钮关闭
Prevent closing by hardware back button in xamarin forms on android
我想通过在 android 上按 xamarin 表单中的硬件后退按钮来防止关闭应用程序。
我希望您可以使用应用程序中的硬件后退按钮进行导航(有效),但不想在到达导航堆栈中的第一页时退出。
我试过在xamarin forms中使用OnSleep事件,但是这里我无法取消退出。
我还尝试在 android 中捕捉后退按钮:
public override void OnBackPressed()
{
//base.OnBackPressed();
}
但是在使用xamarin forms时,我不知道当前显示的是哪个页面。所以我不知道是否允许导航返回
这是适用于 Android 的解决方案。
在应用程序中引入一个计数器 class 并随着每个 OnStart
递增它并随着每个 OnStop
递减它,当计数器为 1 你'我会知道你已经到了最后 activity.
不用说,使用基础 activity 实现,这样您就不必复制过去的样板代码。
它适用于评估 NavigationStack(当您使用 NavigationPage 时)。
在我的 Activity 中,我覆盖了 OnBackPressed
public override void OnBackPressed()
{
if(App.Instance.DoBack)
{
base.OnBackPressed();
}
}
在我的 xamarin forms 应用程序中(App.Instance(它是一个单例)),我将像这样评估当前页面的 NavigationStack。
public bool DoBack
{
get
{
NavigationPage mainPage = MainPage as NavigationPage;
if (mainPage != null)
{
return mainPage.Navigation.NavigationStack.Count > 1;
}
return true;
}
}
当NavigationStack只剩下一页时,我不会调用base.OnBackPressed,这样我就不会关闭应用程序。
![测试]
下面是 Xamarin Forms MasterDetail 页面场景的代码...
public bool DoBack
{
get
{
MasterDetailPage mainPage = App.Current.MainPage as MasterDetailPage;
if (mainPage != null)
{
bool canDoBack = mainPage.Detail.Navigation.NavigationStack.Count > 1 || mainPage.IsPresented;
// we are on a top level page and the Master menu is NOT showing
if (!canDoBack)
{
// don't exit the app just show the Master menu page
mainPage.IsPresented = true;
return false;
}
else
{
return true;
}
}
return true;
}
}
只要在你想阻止的页面中给一个空白调用,比如
protected override bool OnBackButtonPressed()
{
return true;
}
这将阻止 XF-Droid 中的后退按钮。
提出的解决方案可以很好地工作,但我不喜欢"static property exposure"解决问题。此外,我不喜欢使用 "properties as methods" 解决方案,尤其是当涉及到很多逻辑时。
这里的主要问题是我们如何处理 Xamarin.Forms.Application class.
中的 OnBackButton() 方法
如何以更优雅的方式做同样的事情?
首先,您需要像这样扩展 Xamarin.Forms.Application class:
namespace YourNameSpace
{
public class Application : Xamarin.Forms.Application
{
#region Public Methods
public bool HandleBackButton()
{
return OnBackPressed();
}
#endregion
#region Application Methods
protected virtual bool OnBackPressed()
{
return false;
}
#endregion
}
}
您的应用程序实施现在将使用此 class 作为基础 class。请记住相应地修改您的 xaml 和 xaml.cs:
<common:Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:common="clr-namespace:YourNameSpace"
x:Class="YourNameSpace.App">
</common:Application>
在您的 App.cs 实现中,您现在可以覆盖 OnBackButton() 方法。
public partial class App : YourNameSpace.Application
{
#region Constructors
public App()
{
InitializeComponent();
}
#endregion
#region App Methods
protected override bool OnBackPressed()
{
// Handle when the back button is pressed
return false;
}
#endregion
}
然后你需要稍微改变你的 Activity class 实现。
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
#region Constants and Fields
private App _app;
#endregion
#region Activity Methods
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
_app = new App();
LoadApplication(_app);
}
public override void OnBackPressed()
{
if(!_app.HandleBackButton())
base.OnBackPressed();
}
#endregion
}
扩展 Chris 的答案,因为现在没有 App.Instance
,并且无法在平台代码中以静态方式访问 App
。
1. App.xaml.cs
在共享项目中
public bool DoBack
{
get
{
return MainPage.Navigation.NavigationStack.Count > 1;
}
}
2.MainActivity.cs
在 Android 项目中
- 在class中声明一个变量:
App app;
- 在
OnCreate(Bundle bundle)
中将 LoadApplication(new App());
更改为:
app = new App();
LoadApplication(app);
- 覆盖
OnBackPressed()
方法:
public override void OnBackPressed()
{
if (app.DoBack)
{
base.OnBackPressed();
}
}
您可以使用这个 nuget
chd.hwBackButtonManager nuget
我想通过在 android 上按 xamarin 表单中的硬件后退按钮来防止关闭应用程序。
我希望您可以使用应用程序中的硬件后退按钮进行导航(有效),但不想在到达导航堆栈中的第一页时退出。
我试过在xamarin forms中使用OnSleep事件,但是这里我无法取消退出。
我还尝试在 android 中捕捉后退按钮:
public override void OnBackPressed()
{
//base.OnBackPressed();
}
但是在使用xamarin forms时,我不知道当前显示的是哪个页面。所以我不知道是否允许导航返回
这是适用于 Android 的解决方案。
在应用程序中引入一个计数器 class 并随着每个 OnStart
递增它并随着每个 OnStop
递减它,当计数器为 1 你'我会知道你已经到了最后 activity.
不用说,使用基础 activity 实现,这样您就不必复制过去的样板代码。
它适用于评估 NavigationStack(当您使用 NavigationPage 时)。
在我的 Activity 中,我覆盖了 OnBackPressed
public override void OnBackPressed()
{
if(App.Instance.DoBack)
{
base.OnBackPressed();
}
}
在我的 xamarin forms 应用程序中(App.Instance(它是一个单例)),我将像这样评估当前页面的 NavigationStack。
public bool DoBack
{
get
{
NavigationPage mainPage = MainPage as NavigationPage;
if (mainPage != null)
{
return mainPage.Navigation.NavigationStack.Count > 1;
}
return true;
}
}
当NavigationStack只剩下一页时,我不会调用base.OnBackPressed,这样我就不会关闭应用程序。
![测试]
下面是 Xamarin Forms MasterDetail 页面场景的代码...
public bool DoBack
{
get
{
MasterDetailPage mainPage = App.Current.MainPage as MasterDetailPage;
if (mainPage != null)
{
bool canDoBack = mainPage.Detail.Navigation.NavigationStack.Count > 1 || mainPage.IsPresented;
// we are on a top level page and the Master menu is NOT showing
if (!canDoBack)
{
// don't exit the app just show the Master menu page
mainPage.IsPresented = true;
return false;
}
else
{
return true;
}
}
return true;
}
}
只要在你想阻止的页面中给一个空白调用,比如
protected override bool OnBackButtonPressed()
{
return true;
}
这将阻止 XF-Droid 中的后退按钮。
提出的解决方案可以很好地工作,但我不喜欢"static property exposure"解决问题。此外,我不喜欢使用 "properties as methods" 解决方案,尤其是当涉及到很多逻辑时。
这里的主要问题是我们如何处理 Xamarin.Forms.Application class.
中的 OnBackButton() 方法如何以更优雅的方式做同样的事情?
首先,您需要像这样扩展 Xamarin.Forms.Application class:
namespace YourNameSpace
{
public class Application : Xamarin.Forms.Application
{
#region Public Methods
public bool HandleBackButton()
{
return OnBackPressed();
}
#endregion
#region Application Methods
protected virtual bool OnBackPressed()
{
return false;
}
#endregion
}
}
您的应用程序实施现在将使用此 class 作为基础 class。请记住相应地修改您的 xaml 和 xaml.cs:
<common:Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:common="clr-namespace:YourNameSpace"
x:Class="YourNameSpace.App">
</common:Application>
在您的 App.cs 实现中,您现在可以覆盖 OnBackButton() 方法。
public partial class App : YourNameSpace.Application
{
#region Constructors
public App()
{
InitializeComponent();
}
#endregion
#region App Methods
protected override bool OnBackPressed()
{
// Handle when the back button is pressed
return false;
}
#endregion
}
然后你需要稍微改变你的 Activity class 实现。
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
#region Constants and Fields
private App _app;
#endregion
#region Activity Methods
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
_app = new App();
LoadApplication(_app);
}
public override void OnBackPressed()
{
if(!_app.HandleBackButton())
base.OnBackPressed();
}
#endregion
}
扩展 Chris 的答案,因为现在没有 App.Instance
,并且无法在平台代码中以静态方式访问 App
。
1. App.xaml.cs
在共享项目中
public bool DoBack
{
get
{
return MainPage.Navigation.NavigationStack.Count > 1;
}
}
2.MainActivity.cs
在 Android 项目中
- 在class中声明一个变量:
App app;
- 在
OnCreate(Bundle bundle)
中将LoadApplication(new App());
更改为:
app = new App();
LoadApplication(app);
- 覆盖
OnBackPressed()
方法:
public override void OnBackPressed()
{
if (app.DoBack)
{
base.OnBackPressed();
}
}
您可以使用这个 nuget chd.hwBackButtonManager nuget