Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

[Android] wire up the correct toolbar to SetSupportActionBar #4893

Closed
wants to merge 5 commits into from

Conversation

PureWeen
Copy link
Contributor

@PureWeen PureWeen commented Jan 4, 2019

Description of Change

I finished up this PR knowing it would be slightly breaking but then realized it causes the back button on Android to operate differently than iOS which maybe was intentional?

is the purpose of this code

AToolbar bar;
if (ToolbarResource != 0)
{
bar = LayoutInflater.Inflate(ToolbarResource, null).JavaCast<AToolbar>();
if (bar == null)
throw new InvalidOperationException("ToolbarResource must be set to a Android.Support.V7.Widget.Toolbar");
}
else
bar = new AToolbar(this);
SetSupportActionBar(bar);

To make it so that the software back button doesn't fire the OnBackButtonPressed of the contentpage on Android?

The Visible toolbar is created on the NavigationRenderer

void SetupToolbar()
{
Context context = Context;
var activity = (FormsAppCompatActivity)context;
AToolbar bar;
if (FormsAppCompatActivity.ToolbarResource != 0)
bar = activity.LayoutInflater.Inflate(FormsAppCompatActivity.ToolbarResource, null).JavaCast<AToolbar>();
else
bar = new AToolbar(context);
bar.SetNavigationOnClickListener(this);
AddView(bar);
_toolbar = bar;
}

So SetSupportActionBar(bar); isn't using the right toolbar which means this code never runs

public override bool OnOptionsItemSelected(IMenuItem item)

I came across this while investigating
#4827

I'll fill out the rest if this PR seems valid

Issues Resolved

Possibly fixes
#2118
Need to research a bit further

Platforms Affected

  • Android

Behavioral/Visual Changes

Clicking the software backbutton on Android will now fire the OnBackButtonPressed on Android

Also now on startup we're only inflating the toolbar view once opposed to twice

Testing Procedure

Run the included Issue

PR Checklist

  • Has automated tests
  • Rebased on top of the target branch at time of PR
  • Changes adhere to coding standard

@PureWeen PureWeen added the DO-NOT-MERGE-!!! 🛑 This is in progress and needs to be updated before it can be merged. label Jan 4, 2019
else
bar = new AToolbar(this);

SetSupportActionBar(bar);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Outside of intentionally setting the SupportActionBar to the wrong instance of the Toolbar and thus breaking software back button events. I'm not quite sure what the purpose of this code is

@PureWeen PureWeen removed the DO-NOT-MERGE-!!! 🛑 This is in progress and needs to be updated before it can be merged. label Jan 7, 2019
@samhouts samhouts added p/Android breaking Changes behavior or appearance e/3 🕒 3 labels Jan 7, 2019
@samhouts samhouts added this to In Review in v3.6.0 Jan 7, 2019
@hartez
Copy link
Contributor

hartez commented Jan 11, 2019

I doubt that the purpose of setting up the toolbar outside of the NativationPageRenderer was to mess with the back button. That's a lot of effort to go to just to stop the back button from working.

So what you are saying is that your change fixes the issue, but it also causes the back button to behave differently? Can you elaborate on how it's different (and how it compares to iOS?)

Copy link
Contributor

@hartez hartez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need more info.

@PureWeen
Copy link
Contributor Author

PureWeen commented Jan 11, 2019

@hartez so right now the OnBackButtonPressed override on Page only executes for the hardware button on Android and on UWP. If you click the software BackButton (from a navigation page) on iOS or android that method doesn't fire

This PR fixes it on Android but it doesn't on iOS. I know there was a lot of talk around iOS and OnBackButtonPressed but I think that was mainly around not tying swipe to OnBackButtonPressed

If this PR seems valid then we should probably mark this one DNM and I should also make it so OnBackButtonPressed fires for the software button on iOS

Or Merge this one so it gets applied and then schedule an iOS fix for the near future

@samhouts samhouts moved this from In Review to In Progress in v3.6.0 Jan 11, 2019
@hartez
Copy link
Contributor

hartez commented Jan 15, 2019

@hartez so right now the OnBackButtonPressed override on Page only executes for the hardware button on Android and on UWP. If you click the software BackButton (from a navigation page) on iOS or android that method doesn't fire

Yes. And that's the correct behavior, at least according to the documentation. OnBackButtonPressed only applies to the hardware button, and only on platforms which have one (i.e., not iOS):
https://docs.microsoft.com/en-us/dotnet/api/xamarin.forms.navigationpage.onbackbuttonpressed?view=xamarin-forms

This PR fixes it on Android but it doesn't on iOS. I know there was a lot of talk around iOS and OnBackButtonPressed but I think that was mainly around not tying swipe to OnBackButtonPressed

So this PR makes the hardware back button on Android work for NavigationPage after the app resumes?

If this PR seems valid then we should probably mark this one DNM and I should also make it so OnBackButtonPressed fires for the software button on iOS

Or Merge this one so it gets applied and then schedule an iOS fix for the near future

If this fixes the after-resume-hardware-back-button on Android, we should get it merged and have the iOS discussion (if any) elsewhere.

Also, why is this marked with the breaking label?

@PureWeen
Copy link
Contributor Author

To summarize this a bit first

Yes. And that's the correct behavior, at least according to the documentation. OnBackButtonPressed only applies to the hardware button, and only on platforms which have one (i.e., not iOS):
https://docs.microsoft.com/en-us/dotnet/api/xamarin.forms.navigationpage.onbackbuttonpressed?view=xamarin-forms

I'm just curious if that documentation was written because it's always been a bug or the intention initially was for it to work like this?

So this PR makes the hardware back button on Android work for NavigationPage after the app resumes?

No it makes the software back button work after the app resumes or the orientation changes. Really anything that causes the NavigationRenderer to recreate itself. The hardware back button always stays working but the original issues is about how they are trying to make the Software back button work #4827. The workaround in that issue is found a number of places where people suggest how to wire up the OnBackButtonPressed to the Software button. But that workaround breaks whenever the NavigationRenderer is recreated

Since our NavigationRenderer creates a new support bar on Orientation change then the code they have wired up stops working as our current NavigationRenderer doesn't call SetSupportActionBar all we do in our code is set the action bar to some dummy ActionBar that never sees the light of day

Also, why is this marked with the breaking label?
Because it makes it so the software back button now fires OnBackButtonPressed

If we want to honor the original documentation and just never enable the SoftwareBackButton then we should just close #1944, #1413, and #4827 and say it's by design

Though it seems like adding an API to enable the Software Back Button to fire OnBackButtonPressed on all three platforms would be super helpful

@hartez
Copy link
Contributor

hartez commented Jan 15, 2019

I'm just curious if that documentation was written because it's always been a bug or the intention initially was for it to work like this?

AFAIK, it has always worked this way. And that makes sense - the hardware back button is not the same thing as "navigating back". The hardware back button also serves functions like dismissing keyboards, nav drawers, and other stuff. The "back button" provided by the NavigationPage is a distinct UI concept from any hardware buttons provided on Android or UWP.

But looking at the comments in #1944 and #1413, it's clear that the current API (and years of workaround cruft) is causing a bunch of confusion. We need to fix it, but not as part of this PR.

Copy link
Contributor

@hartez hartez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just needs minor changes.

@PureWeen
Copy link
Contributor Author

the hardware back button is not the same thing as "navigating back". The hardware back button also serves functions like dismissing keyboards, nav drawers, and other stuff. The "back button" provided by the NavigationPage is a distinct UI concept from any hardware buttons provided on Android or UWP.

Only thing is that UWP calls OnBackButtonPressed when using the navigate back button.

But yea we should probably provide a specific OnNavigatingBack or similar that ties the navigation concept more directly to intent. As is people keep overriding OnBackButtonPressed and then some permutation of what they test stops the navigation so they think they're good to go.

Maybe even adding a context args to OnBackButtonPressed would help so they know exactly what action is happening they want to respond to.

@@ -66,14 +66,6 @@ public override void OnConfigurationChanged(Configuration newConfig)
ConfigurationChanged?.Invoke(this, new EventArgs());
}

public override bool OnOptionsItemSelected(IMenuItem item)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hartez so I deleted this from our code since it's only purpose (AFAICT) is to call BackPressed when the user clicks the software back arrow. Maybe there's a use case I'm forgetting about though? This allows users to just override OnOptionsItemSelected like I do here https://github.com/xamarin/Xamarin.Forms/pull/4893/files#diff-48c5e139c569153d4219aa3bbb433ceaR104 and will thus resolve #4827

@PureWeen PureWeen added the DO-NOT-MERGE-!!! 🛑 This is in progress and needs to be updated before it can be merged. label Jan 16, 2019
@PureWeen
Copy link
Contributor Author

@hartez @kingces95 I added DNM for now
Hold off on reviewing. I need to test a few more things first

@PureWeen
Copy link
Contributor Author

build --uitests

@PureWeen PureWeen removed the DO-NOT-MERGE-!!! 🛑 This is in progress and needs to be updated before it can be merged. label Jan 16, 2019
@PureWeen
Copy link
Contributor Author

alright @hartez @kingces95 ready for review

@PureWeen PureWeen added the DO-NOT-MERGE-!!! 🛑 This is in progress and needs to be updated before it can be merged. label Jan 17, 2019
@kingces95
Copy link
Contributor

Can do a review now. But do we wait for tests to pass?

@PureWeen
Copy link
Contributor Author

@kingces95 just wait for now

I ran into some additional issues with this PR that will need to be addressed first which is probably why the tests are failing

@samhouts samhouts added this to In Progress in v4.0.0 Feb 2, 2019
@samhouts samhouts removed this from In Progress in v3.6.0 Feb 2, 2019
@samhouts samhouts added this to In Progress in v4.1.0 Mar 2, 2019
@samhouts samhouts removed this from In Progress in v4.0.0 Mar 2, 2019
@PureWeen PureWeen closed this Apr 22, 2019
v4.1.0 automation moved this from In Progress to Closed Apr 22, 2019
@samhouts samhouts removed this from Closed in v4.1.0 May 29, 2019
@pauldiston
Copy link

Having upgraded from XF 3.3 to XF 4.0 yesterday I am experiencing a number of issues, one being OnOptionsItemSelected isn't called any longer, which I presume is a result of the incorrect toolbar being wired up, hence this PR.
For clarification, this comment "samhouts removed this from Closed in vNext (4.1.0) 9 days ago", does this mean that this issue will be resolved in XF 4.1?
I have tried the setting of the toolbar "manually" from (https://forums.xamarin.com/discussion/67854/android-menu-and-back-button-not-working) but I don't seem to be able to get this working. If I have to wait until XF 4.1 for this to be resolved then so be it, as I am already waiting for issues to be resolved with the CarouselView which is planned for XF 4.1 as well.

@pauldiston
Copy link

@samhouts Would you be able to provide any information regarding the question I had about the comment?

@samhouts
Copy link
Member

@pauldiston This was not merged, so it will not be resolved yet. There was a workaround described in #4827 (comment) that may help you.

@PureWeen fyi

@samhouts samhouts added this to In Progress in v4.2.0 Jul 2, 2019
@samhouts samhouts removed this from In Progress in v4.2.0 Jul 4, 2019
@samhouts samhouts added the inactive Issue is older than 6 months and needs to be retested label Oct 2, 2019
@samhouts samhouts added this to In Progress in v4.4.0 Oct 2, 2019
@samhouts samhouts added the in-progress This issue has an associated pull request that may resolve it! label Oct 2, 2019
@samhouts samhouts removed this from In Progress in v4.4.0 Nov 2, 2019
@pauldiston
Copy link

@samhouts Having parked this issue back in June 2019, I am back again with the same issue in version 4.5.0.430. Having tried a work around I found here (https://theconfuzedsourcecode.wordpress.com/2017/03/02/formsappcompatactivity-is-not-calling-onoptionsitemselected-xamarin-android/) I am now running into this issue (#2118).
There must be a way of handling the OnOptionsItemSelected without having all these problems.

@pauldiston
Copy link

@samhouts After further investigation, is seems that everytime I want to set the toolbar items for a page I need to call SetSupportActionBar, doing it in the OnCreate is just not enough. Time to add my SetToolbar method call to each page that has toolbar items.

@samhouts samhouts added this to In Progress in vCurrent (4.8.0) Apr 28, 2020
@samhouts samhouts removed in-progress This issue has an associated pull request that may resolve it! inactive Issue is older than 6 months and needs to be retested labels May 1, 2020
@samhouts samhouts removed this from In Progress in vCurrent (4.8.0) Jul 30, 2020
@PureWeen PureWeen deleted the fix4827 branch January 7, 2021 22:34
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
breaking Changes behavior or appearance DO-NOT-MERGE-!!! 🛑 This is in progress and needs to be updated before it can be merged. e/3 🕒 3 p/Android t/bug 🐛
Projects
None yet
Development

Successfully merging this pull request may close these issues.

OnOptionsItemSelected() not called after a configuration/orientation change.
5 participants