New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

No way to detect software back button click in Android device in Xamarin.Forms application that uses MvvmCross. #3124

Closed
artakhak opened this Issue Sep 25, 2018 · 15 comments

Comments

Projects
None yet
4 participants
@artakhak

artakhak commented Sep 25, 2018

馃悰 Bug Report

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 (we basically return true in this method and handle the back button based on result of prompt.

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.

Expected behavior

Reproduction steps

Configuration

Version: 6.x

Platform:

  • 馃摫 iOS
  • 馃 Android
  • 馃弫 WPF
  • 馃寧 UWP
  • 馃崕 MacOS
  • 馃摵 tvOS
  • 馃悞 Xamarin.Forms
@FabriBertani

This comment has been minimized.

Show comment
Hide comment
@FabriBertani

FabriBertani Sep 28, 2018

If you're using Xamarin Forms you can override the OnBackButtonPressed method on the code behind of your xaml.

FabriBertani commented Sep 28, 2018

If you're using Xamarin Forms you can override the OnBackButtonPressed method on the code behind of your xaml.

@artakhak

This comment has been minimized.

Show comment
Hide comment
@artakhak

artakhak Sep 28, 2018

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.

artakhak commented Sep 28, 2018

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.

@nickrandolph

This comment has been minimized.

Show comment
Hide comment
@nickrandolph

nickrandolph Sep 28, 2018

Contributor

Closing this issue because:
a) This is an issue with XF (see xamarin/Xamarin.Forms#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 鈥
Contributor

nickrandolph commented Sep 28, 2018

Closing this issue because:
a) This is an issue with XF (see xamarin/Xamarin.Forms#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 鈥
@artakhak

This comment has been minimized.

Show comment
Hide comment
@artakhak

artakhak Sep 28, 2018

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 鈥

artakhak commented Sep 28, 2018

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 鈥
@artakhak

This comment has been minimized.

Show comment
Hide comment
@artakhak

artakhak Sep 28, 2018

Could you please re-open the issue, since the issue is not solved

artakhak commented Sep 28, 2018

Could you please re-open the issue, since the issue is not solved

@nickrandolph

This comment has been minimized.

Show comment
Hide comment
@nickrandolph

nickrandolph Sep 28, 2018

Contributor

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

Contributor

nickrandolph commented Sep 28, 2018

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

@artakhak

This comment has been minimized.

Show comment
Hide comment
@artakhak

artakhak Sep 28, 2018

@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 鈥

artakhak commented Sep 28, 2018

@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 鈥
@FabriBertani

This comment has been minimized.

Show comment
Hide comment
@FabriBertani

FabriBertani Sep 29, 2018

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 commented Sep 29, 2018

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.

@nickrandolph

This comment has been minimized.

Show comment
Hide comment
@nickrandolph

nickrandolph Sep 29, 2018

Contributor

@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.

Contributor

nickrandolph commented Sep 29, 2018

@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.

@nickrandolph

This comment has been minimized.

Show comment
Hide comment
@nickrandolph

nickrandolph Sep 29, 2018

Contributor

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.

Contributor

nickrandolph commented Sep 29, 2018

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.

@artakhak

This comment has been minimized.

Show comment
Hide comment
@artakhak

artakhak Sep 29, 2018

@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 鈥

artakhak commented Sep 29, 2018

@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 鈥
@nickrandolph

This comment has been minimized.

Show comment
Hide comment
@nickrandolph

nickrandolph Sep 29, 2018

Contributor

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

Contributor

nickrandolph commented Sep 29, 2018

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

@nickrandolph

This comment has been minimized.

Show comment
Hide comment
@nickrandolph

nickrandolph Oct 1, 2018

Contributor

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.
Contributor

nickrandolph commented Oct 1, 2018

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.
@artakhak

This comment has been minimized.

Show comment
Hide comment
@artakhak

artakhak Oct 1, 2018

@ 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.

artakhak commented Oct 1, 2018

@ 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment