We want to prompt the user when the back button is pressed (since a critical task might be executed when the user presses the back button).
We were able to implement this for UWP and Android device hardware back button by overriding the method bool OnBackButtonPressed() in MvvmCross.Forms.Views.MvxContentPage
The problem is that OnBackButtonPressed() is never executed when Android software back button is pressed.
Based on this blog https://theconfuzedsourcecode.wordpress.com/2017/03/12/lets-override-navigation-bar-back-button-click-in-xamarin-forms/ this should be implemented in android project by overriding OnOptionsItemSelected(IMenuItem item) and handling the logic in overridden method. However, the overridden method MvvmCross.Forms.Platforms.Android.Views.MvxFormsAppCompatActivity.OnOptionsItemSelected(IMenuItem item) is never executed. Since this works in Xamarin.Forms (in the example at the link above) I expect the problem is with MvvmCross
We have the latest version of MvvmCross.
Version: 6.x
Platform:
If you're using Xamarin Forms you can override the OnBackButtonPressed method on the code behind of your xaml.
Fabricio,
Thanks for the response, however as I mentioned in the issue, I already override OnBackButtonPressed() in code behind file of the page xaml.
However the problem is that OnBackButtonPressed() is never executed when Android software back button is pressed.
So overriding this method works for UWP, and Android hardware back button clicks. However, this does not work when the software back button is clicked in android device.
Closing this issue because:
a) This is an issue with XF (see https://github.com/xamarin/Xamarin.Forms/issues/1944)
b) There are some workarounds for this: https://theconfuzedsourcecode.wordpress.com/2017/03/12/lets-override-navigation-bar-back-button-click-in-xamarin-forms
ĂĂžĆfuzëà SĂžurcĂ«ĂĂždĂ«
So you would like to override the Navigation Bar back button click event in your Xamarin Forms App? ;) Yeah could be for a Sign up Page, Order Details Page, or any kind of a Page where you want to âŠ
The workaround in https://theconfuzedsourcecode.wordpress.com/2017/03/12/lets-override-navigation-bar-back-button-click-in-xamarin-forms/ does not work in MvvmCross since MvvmCross.Forms.Platforms.Android.Views.MvxFormsAppCompatActivity.OnOptionsItemSelected(IMenuItem item) is never executes. This was mentioned in the issue.
I mentioned in the issue that the workaround with overriding OnOptionsItemSelected() works in Xamarin.Forms according to https://theconfuzedsourcecode.wordpress.com/2017/03/12/lets-override-navigation-bar-back-button-click-in-xamarin-forms/ . Therefore, since I can't use this solution because the method MvvmCross.Forms.Platforms.Android.Views.MvxFormsAppCompatActivity.OnOptionsItemSelected(IMenuItem item) is never executes, this must be an MvvmCross issue.
ĂĂžĆfuzëà SĂžurcĂ«ĂĂždĂ«
So you would like to override the Navigation Bar back button click event in your Xamarin Forms App? ;) Yeah could be for a Sign up Page, Order Details Page, or any kind of a Page where you want to âŠ
Could you please re-open the issue, since the issue is not solved
See open XF issue I referenced above.
If you think this issue has been solved then please provide an XF sample (without MvvmCross) that shows it working and I'll investigate further.
Alternatively, please download the source code and run the Playground sample and point out where you believe Mvx breaks the ability to use the workaround
@nickrandolph
I know that XF works based on example in https://theconfuzedsourcecode.wordpress.com/2017/03/12/lets-override-navigation-bar-back-button-click-in-xamarin-forms/
I know that something is wrong in MvvmCros, since we subclass MvvmCross.Forms.Platforms.Android.Views.MvxFormsAppCompatActivity in Android project and the application runs fine in Android device, except that the method MvvmCross.Forms.Platforms.Android.Views.MvxFormsAppCompatActivity.OnOptionsItemSelected(IMenuItem item) I override never executes, therefore I cannot use the solution in https://theconfuzedsourcecode.wordpress.com/2017/03/12/lets-override-navigation-bar-back-button-click-in-xamarin-forms/ .
If you think this is not enough evidence that MvvmCross has an issue, I can download Playground sample and see what it is doing to point out the same issue there. However, doing so will take more time.
At least, please re-open the issue, since the issue is not solved.
ĂĂžĆfuzëà SĂžurcĂ«ĂĂždĂ«
So you would like to override the Navigation Bar back button click event in your Xamarin Forms App? ;) Yeah could be for a Sign up Page, Order Details Page, or any kind of a Page where you want to âŠ
Did you try to initialize the task you need by a command on the viewmodel and execute that command on the override OnBackButtonPressed method from the xaml? OnBackButtonPressed is from XF and it should work with the hardware back button, at least I never have any kind of problem with it.
@FabriBertani I might be wrong but the issue isn't with the hardware back button. It's with the software back button that appears by default when using a navigationpage and navigating to a secondary page. My preference is to hide the default navigation bar but I think there is an issue intercepting the back button in the navigation bar because it's a native component. I don't believe this is currently an MVX issue but if we can repro this in the playground I'd be happy to re-open this issue.
I just created a new XF project using the Master-Detail template provided in VS. I added the OnOptionsItemSelected override. Unfortunately the override is not called when any of the menu items are tapped, including the software back button. At this stage this confirms there is still an issue with XF and thus I won't reopen this issue at this point.
Again, happy to be shown otherwise if we can validate that Mvx is in fact breaking the way XF works.
@nickrandolph Thanks for trying out this in XF project. I appreciate the effort. Yes I agree if the overridden method OnOptionsItemSelected () is not execuited in XF than it is a XF issue. Based on the solution at https://theconfuzedsourcecode.wordpress.com/2017/03/12/lets-override-navigation-bar-back-button-click-in-xamarin-forms/ it looks they somehow were able to make this work, but probably there something they did in XF project to make this work
At this point I adon't insist that the issue be re-opened, since you validated that this is not a MvvmCross issue. Will try XF project at some point to see what can be done to overcome this issue. If I find a solution, will post a solution.
Thanks.
ĂĂžĆfuzëà SĂžurcĂ«ĂĂždĂ«
So you would like to override the Navigation Bar back button click event in your Xamarin Forms App? ;) Yeah could be for a Sign up Page, Order Details Page, or any kind of a Page where you want to âŠ
Tbh I don't like the standard nav bar, so I typically remove it anyhow. That way you have 100% control and can make it look the same on all platforms
Ok, I've traced down the issue. It totally is XF that's messing with the ability to hook OnOptionsItemSelected but in a legitimate way. The NavigationPageRenderer (for Android) implements IOnClickListener (https://developer.android.com/reference/android/view/View.OnClickListener) and registering this with the toolbar (which is set as the actionbar). This is all as clear as mud if you trawl through the NavigationPageRenderer (https://github.com/xamarin/Xamarin.Forms/blob/84695d72e2d0885bedf31d5ccd4c60adf033ada4/Xamarin.Forms.Platform.Android/AppCompat/NavigationPageRenderer.cs)
Luckily it also means that this is dead easy to intercept. You can simply create your own custom renderer that inherits from the XF NavigationPageRenderer (do this in your Android project). Unfortunately XF don't seem to understand the concept of protected virtual, which means that nothing's easily overridable. However, in this case the method we want to override, OnClick, is part of the IOnClickListener interface, so we can simply create our own implementation.
The following code for OnClick is exactly the same as the base method, so will function exactly the same. It's up to you how you then use this to control navigation - run this code and set a break point in the OnClick method.
[assembly: ExportRenderer(typeof(NavigationPage), typeof(HackBackButton.CustomNavigationPageRenderer))]
namespace HackBackButton
{
public class CustomNavigationPageRenderer : NavigationPageRenderer, IOnClickListener
{
public CustomNavigationPageRenderer()
{
}
public CustomNavigationPageRenderer(Context context) : base(context)
{
}
public new void OnClick(Android.Views.View v)
{
Element?.PopAsync();
}
}
}
Hope this helps - I'm going to blog this in more detail at some point
Android Developers
GitHub
Xamarin.Forms official home. Contribute to xamarin/Xamarin.Forms development by creating an account on GitHub.
@ nickrandolph This is great news. I appreciate you taking time to get to the bottom of the issue. I will use the solution you suggested.
@nickrandolph Should this still work with Xamarin.Forms 4.3 / 4.4? Because my OnClick method is never called even if I implement it exactly as you suggest. Or is it maybe a problem my app runs a MasterDetail navigation?
using Android.Content;
using MyApp.Core;
using MyApp.Core.ViewModels;
using MyApp.Droid.Renderer;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android.AppCompat;
using static Android.Views.View;
using AView = Android.Views.View;
[assembly: ExportRenderer(typeof(NavigationPage), typeof(CustomNavigationPageRenderer))]
namespace MyApp.Droid.Renderer
{
public class CustomNavigationPageRenderer : NavigationPageRenderer, IOnClickListener
{
public CustomNavigationPageRenderer(Context context)
: base(context)
{ }
public new void OnClick(AView view)
{
var viewModel = FormsApp.GetCurrentActiveViewModel();
if (viewModel is IInterceptBackNavigationViewModel vm && vm.IsDirty)
vm.ShouldNavigateBack();
else
Element?.PopAsync();
}
}
}
Implement the Renderer as above and you can then change the OnClick method to:
public new void OnClick(View v)
{
Element?.SendBackButtonPressed();
}
Then you can override OnBackButtonPressed in the code behind to handle the back request.
Most helpful comment
Ok, I've traced down the issue. It totally is XF that's messing with the ability to hook OnOptionsItemSelected but in a legitimate way. The NavigationPageRenderer (for Android) implements IOnClickListener (https://developer.android.com/reference/android/view/View.OnClickListener) and registering this with the toolbar (which is set as the actionbar). This is all as clear as mud if you trawl through the NavigationPageRenderer (https://github.com/xamarin/Xamarin.Forms/blob/84695d72e2d0885bedf31d5ccd4c60adf033ada4/Xamarin.Forms.Platform.Android/AppCompat/NavigationPageRenderer.cs)
Luckily it also means that this is dead easy to intercept. You can simply create your own custom renderer that inherits from the XF NavigationPageRenderer (do this in your Android project). Unfortunately XF don't seem to understand the concept of protected virtual, which means that nothing's easily overridable. However, in this case the method we want to override, OnClick, is part of the IOnClickListener interface, so we can simply create our own implementation.
The following code for OnClick is exactly the same as the base method, so will function exactly the same. It's up to you how you then use this to control navigation - run this code and set a break point in the OnClick method.
[assembly: ExportRenderer(typeof(NavigationPage), typeof(HackBackButton.CustomNavigationPageRenderer))]
namespace HackBackButton
{
public class CustomNavigationPageRenderer : NavigationPageRenderer, IOnClickListener
{
public CustomNavigationPageRenderer()
{
}
}
Hope this helps - I'm going to blog this in more detail at some point