Hello,
Firstly, some background: We have a requirement within one of our apps to show multiple different pages side by side using Xamarin Forms where you can swipe between pages and quickly jump to a particular page. This app is currently targetted for Android.
TabbedPage appears to do exactly what we want, however the problem we have is performance. As TabbedPage implements MultiPage when you setup the tabs, you have to setup all the Page objects at the same time.
This however can be very slow if there are some complex layouts / large number of elements on the Page in question, e.g. in some cases we can see for 10 tabs it taking around 5seconds to setup all the pages. (and we want it to be far snappier than that)
Ideally what we would like is that the Page is only instantiated when it first appears, I thought of 2 simple options:
Option 1 - Override the implementation of TabbedPage
Unfortunately this doesn't seem possible, as TabbedPage implements MultiPage and some of the code isn't accessible as it uses EditorBrowsable(EditorBrowsableState.Never), it doesn't look we can override the necessary bits to have the tabs detached from the actual Page objects.
Option 2 - Tab Page objects replace itself on appearing
One idea I had was that we create a simple implementation of Page that has no components, and simply has a Func<Page> which when appearing it calls to create the actual page, then replaces itself in the parent TabbedPage. The setup of the TabbedPage even with large numbers of pages is then quick as they are all blank.
Although not an elegant solution, this actually works quite welll, however we run into another issue: Lets say we have a <LoadPage> which when it appears we are replacing with <ActualPage>, for this to work we need to:
- Update the TabbedPage Children array to replace the <LoadPage> with the new <ActualPage>
- Ensure the TabbedPage CurrentPage points to the <ActualPage>
However we then have a chicken and egg situation, if you change the Children first, this immediately triggers the CurrentPage to unset as the <LoadPage> is no longer in Children, which will cause the display to scroll the tab control to the first tab. Then when setting the CurrentPage to <ActualPage> this then correctly moves to the required tab. Essentially, this causes a huge jittering on the display as it scrolls to the first tab and back again, which looks really clunky.
If you try and change the CurrentPage first to <ActualPage> before that page has been replaced in the Children, it knows and unsets the CurrentPage immediately.
Essentially, I really need a method to replace an item in the Children and set CurrentPage at the same time, but as this is within the MultiPage class, it seems I have no control over this.
So my question is does anyone here have any suggestions or better ideas when trying to use TabbedPage or something like it to achieve the same result, where I can instantiate the Page on its first appearing rather than up front when we setup all of the tabs. (or do I just need to plead with Xamarin dev team to see if they can add more flexibility to the TabbedPage implementation?)
MrMoo