xamarin / Xamarin.Forms

Xamarin.Forms is no longer supported. Migrate your apps to .NET MAUI.
https://aka.ms/xamarin-upgrade
Other
5.62k stars 1.87k forks source link

TabbedPage OnAppearing not called when navigated to page first time - android #3855

Open LeoJHarris opened 6 years ago

LeoJHarris commented 6 years ago

Description

When using tabbed page, the OnAppearing method is not always called. When I launch my app all the OnAppearing methods get called for the first time - fine. However when I navigate to another tabbed page the OnAppearing does not get called. Only when I navigate away and back to the tabbed page does the OnAppearing get called. I would expect the OnAppearing to be called anytime the page is appearing.

As a side note I checked and the OnDisappearing method does get called when navigating away from the page for the first time but OnAppearing not when navigating too first time.

Steps to Reproduce

  1. Launch app with two Tabbed Pages with the app landing on the first tabbed page.
  2. Navigate to 2nd tabbedpage first time - check OnAppearing method being called
  3. navigate back to first tabbed page and then back to 2nd tabbed page and OnAppearing method called

Expected Behavior

The 2nd tabbed page's OnAppearing method to be called upon first navigation to this page.

Actual Behavior

The 2nd tabbed page's OnAppearing method does not get called upon first navigation to this page.

Basic Information

Reproduction Link

Sample.zip

kingces95 commented 6 years ago

Behavior as described on droid; When app loads, OnAppearing for tabbed page 1, which has yet to appear on screen, is fired. On iOS, the behavior is as expected. Tested on latest 3.3.0.

jameslavery-zz commented 5 years ago

Do we have an ETA for this being fixed? It's having a material effect on behaviour in our project.

AndreiLazarescu commented 5 years ago

Workaround: Use a simple messaging/notification system and send the notifications manually. Worked for me. In the attached zip there is an example of such a system.

Messenger.zip

jameslavery-zz commented 5 years ago

@AndreiLazarescu Thanks - I could also use the built-in MessagingCenter. How did you implement this to work around the problem? Do you send a message from an Event in the MvxTabbedPage itself? Bearing in mind that the OnAppearing event can't be used!

AndreiLazarescu commented 5 years ago

@jameslavery I encourage you to use the build-in one, it was just as an example in order to avoid confusion with the push notifications. I completely removed the Appearing and Disappearing events and added an event handler on CurrentPageChanged in the TabbedPage. From there I am sending an "Appearing" and an "Disappearing" message with CurrentPage.BindingContext as an parameter. In each PageModel that is child of TabbedPage I have two handlers for those messages where I do a check. If BindingContext (the one sent as an parameter) is the same as my current model (the actual page itself) I do appearing, if not I do disappearing. I also added a flag in each page model that I make true when it is appearing and false when it is disappearing in order to not call the disappearing method for all pages each time a page changes. Below is the behavior:

jameslavery-zz commented 5 years ago

@AndreiLazarescu Thanks - that makes sense. A pity to have to do all this work of course!

AndreiLazarescu commented 5 years ago

@jameslavery Your welcome, glad I could help. Yes, that is true but Xamarin.Forms is still at an early stage, whit time it will mature and these kind of problems will go away. Best of luck with your project!

jamesmontemagno commented 5 years ago

Validated this here in https://github.com/jamesmontemagno/Hanselman.Forms

vjsystematix commented 5 years ago

Any update on this?

MortMH commented 5 years ago

I really need this fixed as well. Would love an update.

ngoquoc commented 5 years ago

I have the same issue with Xamarin Forms 3.4, encountered on Android 6.0.1 (Padfone S, Galaxy S4) and 8.1 (emulator). As a workaround, I subscribed to CurrentPageChanged of the tabbed page, check if it is showing the first child, then call a public method (which simply triggers OnAppearing()) on that child page. The workaround works well, but this issue definitely needs to be fixed.

tdcaesar commented 4 years ago

This is a curious one for me as well. I'm using Xamarin 4.4.0 and when running on Android, the behavior is not as I expected it. I expect when changing from Tab1 to Tab2 that Tab1.OnDisappearing() would fire and Tab2.OnAppearing() would fire after. This seems to happen when tapping on the tab on the navigation bar. However, when swiping left or right to change the tab, the Tab1.OnDisappearing() is delayed. It doesn't fire until there is a second swipe back to the original tab or on to a third tab. This is no good because I cannot predict the behavior of the user and I need to take action between tab changes.
Also, there is no tab tracking on the TabbedPage to tell me what tab I am changing from and to, only current. I only know the latest tab so I cannot force OnDisappearing() naturally from the TabbedPage. The OnAppearing and OnDisappering methods are private so you cannot call them directly from the TabbedPage.

As a workaround, I'm using a combination of an interface for the pages that require the behavior and overriding the TabbedPage to track the CurrentPage before it is changed.

public interface IShowable {
  void OnShow();
  void OnHide();
}
public partial class TestViewModel: IShowable 
{
  public void OnShow() { //DoSomething }
  public void OnHide() { //DoSomething }
}
public partial class MainPage:  TabbedPage
{
  private Xamarin.Forms.Page myCurrentPage;  
  protected override void OnCurrentPageChanged()
  {
    if(myCurrentPage.BindingContext is IShowable )
    {
      (myCurrentPage.BindingContext as IShowable ).OnHide();  
    }
    base.OnCurrentPageChanged(); 
    myCurrentPage = CurrentPage;   

    if(myCurrentPage.BindingContext is IShowable )
    {
      (myCurrentPage.BindingContext as IShowable ).OnShow();  
    }
}

You could apply the interface at the Page level.

It would be better if OnDisappear simply fired when the page disappears. Is there any plan for a fix?

kevin-mueller commented 4 years ago

The Problem still exists roughly 1.5 years later..

FreakyAli commented 4 years ago

The issue still exists roughly 2 years later!!!!

RadoslawKubas commented 4 years ago

I noticed one more strange behaviour, I have TabbedPage with 5 tabs (ContentPage1|ContentPage2|ContentPage3|ContentPage4|NavigationPage/ContentPage5). When starting the app on iOS everything is as expected, OnAppearing on the 1st tab page is called. On Android I noticed that during startup also OnApearing from 5th tab is called, what is problematic.

nbsoftware commented 4 years ago

This very very big issue is still happening in latest XF 4.7 - ouch!

nbsoftware commented 4 years ago

Take the attached TabbedPageWithNavigationPage XF sample. Modified only to display the OnAppearing / OnDisappearing events

TabbedPageWithNavigationPage.zip

On Android, the events are totally not consistent:

Android

Launch
################## OnAppearing TodayPage
################## OnAppearing SchedulePage

Select tab "Schedule"
################## OnDisappearing TodayPage

Select tab "Settings"
################## OnAppearing SettingsPage
################## OnDisappearing SchedulePage

Select tab "Schedule"
################## OnAppearing SchedulePage
################## OnDisappearing SettingsPage

Select tab "Today"
################## OnAppearing TodayPage
################## OnDisappearing SchedulePage

It should be on par with iOS, which is consistent - even the order (OnDisappearing fired before the OnAppearing)

iOS

Launch
################## OnAppearing TodayPage

Select tab "Schedule"
################## OnDisappearing TodayPage
################## OnAppearing SchedulePage

Select tab "Settings"
################## OnDisappearing SchedulePage
################## OnAppearing SettingsPage

Select tab "Schedule"
################## OnDisappearing SettingsPage
################## OnAppearing SchedulePage

Select tab "Today"
################## OnDisappearing SchedulePage
################## OnAppearing TodayPage

Do you plan to fix the Android behavior very soon?

nbsoftware commented 4 years ago

I noticed one more strange behaviour, I have TabbedPage with 5 tabs (ContentPage1|ContentPage2|ContentPage3|ContentPage4|NavigationPage/ContentPage5). When starting the app on iOS everything is as expected, OnAppearing on the 1st tab page is called. On Android I noticed that during startup also OnApearing from 5th tab is called, what is problematic.

I concur. This is a regression because it worked at least in XF 3.5.0.169047 (the last known working version as far as I'm concerned

neoviz commented 4 years ago

I swear this was working as expected on my first deployment to the iOS App Store, but since then, somewhere along the way, has reverted to this buggy behaviour described here. Very frustrating when I had a tested working app, which I can no longer build as-is, and have to find a workaround for. ETA for a fix?

codevon commented 3 years ago

same issue +1

OrtizJorge97 commented 3 years ago

Same issue here in January 12 2021 with Xamarin Forms: 4.8.0.1269.

Umer-Mahmood commented 3 years ago

Same issue here on January 28th, 2021. Xamarin Forms 5.0.0.1874

OrtizJorge97 commented 3 years ago

Same issue here on January 28th, 2021. Xamarin Forms 5.0.0.1874

@Umer-Mahmood how did you manage to solve it?

AlleSchonWeg commented 3 years ago

Override OnCurrentPageChanged in your TabbedPage and call a method in your page.


protected override void OnCurrentPageChanged() {
  base.OnCurrentPageChanged();
  var yourPage = (TodayPage)CurrentPage;
  yourPage.YourInitMhethod();
}
durandt commented 3 years ago

This makes TabbedPage behavior very inconsistent between iOS and Android and is likely to confuse new Xamarin.Forms developers a lot. Fixing this should be high prio, considering for how long this issue has been around.

smalgin commented 3 years ago

I am waiting on this for more than a year!

Elinareso commented 3 years ago

I'm using the latest version of XF 5 and the issue is still there. I have to add the following code in the CurrentPageChanged event to call the OnViewAppearing in the first tab of the views, this means that the first time the OnAppearing event is being call twice.

private readonly List<string> _pages = new List<string>();

private void MainPage_CurrentPageChanged(object sender, EventArgs e)
{
    var page = (CurrentPage as NavigationPage)?.RootPage;

    if (page == null) return;

    var pageName = page.GetType().Name;

    if (_pages.Contains(pageName).Equals(false))
    {
        _pages.Add(pageName);

        ((ViewModelBase)page.BindingContext).OnViewAppearingAsync();
    }
}
smalgin commented 3 years ago

As a matter of fact, the healthy programming pattern with Xamarin UI is to expect things to be called multiple times.

For example, ComboBox IndexChanged event will be called multiple times during page appearance.

I use this safety check everywhere to avoid 'thrashing':

if (newIndex == _currentIndex)
    return;
. . .
if (newState.Equals(_currentState)
    return;

In some places it works well with Stateful (State) pattern (https://en.wikipedia.org/wiki/State_pattern)

JorgeTorresPadron commented 2 years ago

Still waiting for this

AndreiLazarescu commented 2 years ago

@JorgeTorresPadron Have you tried MAUI?

durandt commented 1 year ago

@AndreiLazarescu We have tried MAUI and it is plagued by the exact same issue: https://github.com/dotnet/maui/issues/9531

AndreiLazarescu commented 1 year ago

@durandt Really!? That is kind of bad, I was planning to use MAUI next month. Will keep you posted regarding this.

durandt commented 1 year ago

@AndreiLazarescu We are just starting to use MAUI and will commit to it anyway. UI is more slick and seems more thought through, better animations etc... But I guess there will always be some things you have to work around in such a framework. This bug is even worse in MAUI as, not only OnAppearing isn't called, but it seems the view/page not receiving OnAppearing is also not re-layouting when new data is added. I will try to add a repro to the MAUI issue in the comming days.