Forum Xamarin Xamarin.Forms

Shell close animation stuttering on Android

GraverobberGraverobber Member ✭✭✭
edited November 2019 in Xamarin.Forms

Hi,

today I experimented a bit with the "new" (not that new anymore) shell component in order to set up a simple hamburger menu.
I'm facing the same issue as with the MasterDetailPage in the past, were the animation of closing the menu is stuck for a second before actually closing.
For the Masterdetail it was solved by adding a delay (which was bad already) but I can't find a way to solve it for shell.

Does anyone know how to improve the closing animation? Right now it is unusable.

Here is my xaml setup:

<?xml version="1.0" encoding="UTF-8"?>
<Shell BackgroundColor="#D4503B"  xmlns="http://xamarin.com/schemas/2014/forms" xmlns:page="clr-namespace:MyApp.ContentPages" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="MyApp.AppShell">
    <FlyoutItem Title="Dashboard" >
            <Tab>
                <ShellContent ContentTemplate="{DataTemplate page:Page1}"/>
            </Tab>
    </FlyoutItem>
    <FlyoutItem Title="Train ticket request">
            <Tab>
                <ShellContent ContentTemplate="{DataTemplate page:Page2}" />
            </Tab>
    </FlyoutItem>
    <FlyoutItem Title="Parking spot reservation">
            <Tab>
                <ShellContent ContentTemplate="{DataTemplate page:Page3}" />
            </Tab>
    </FlyoutItem>
</Shell>

Page 1 is almost empty, just two buttons without any styling are shown there but the same problem. Page2 and 3 are a bit more complex but still not overwhelmingly crazy.

One of my ideas was to manually tell when to open and close and navigate but I didn't find a way how to implement it (For example, how to get the menu icon click event?)
Any ideas?

I'm using Xamarin.Forms 4.3.0.947036

References confirming the bug (One is marked as solved but clearly isn't):
https://github.com/xamarin/Xamarin.Forms/issues/7521
https://github.com/xamarin/Xamarin.Forms/issues/5216

References to fix MasterDetail in the past:
https://github.com/xamarin/Xamarin.Forms/issues/4398
https://stackoverflow.com/questions/48115810/how-can-i-make-the-masterdetailpage-faster-on-android

Answers

  • JarvanJarvan Member, Xamarin Team Xamurai

    One of my ideas was to manually tell when to open and close and navigate

    Xamarin.Forms Shell includes a URI-based navigation experience that uses routes to navigate to any page in the application, without having to follow a set navigation hierarchy. Shell class provides the GoToAsync method to perform navigation.

    You can navigate to a page manayally in code by the method.

    await Shell.Current.GoToAsync("//animals/monkeys");
    

    For more details, check the Tutorial about Shell.Navigation.
    https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/shell/navigation

  • GraverobberGraverobber Member ✭✭✭

    Thank you for your response @Jarvan,

    I was aware of The Uri like pattern/navigation, though I didn't try it yet, but the question is
    will the call to GoToAsync also close the menu? If yes will it solve the issue of the lagging animation?
    I also don't see how to intercept the click on a menu item and call The Uri manually in order to avoid the normal shell navigation.
    I can listen for the CurrentItem property to change but when that happens, it will already navigate to the page.

    I have to try a bit with The Uri like navigation to see if it allows to solve the issue.

    Thank you.

  • JarvanJarvan Member, Xamarin Team Xamurai

    Hi, what's the result? Any updates?

  • GraverobberGraverobber Member ✭✭✭

    Hi @Jarvan,

    thank you for your will to help :D

    I still don't know how to proceed with the Uri Pattern.
    I understand how it works and for example if I have a button on a page it is easy to execute it.

    However the idea would be to use it instead of the default navigation system but there are two links missing for me in order to implement it.
    1. How to intercept the click on the menu icon to open the menu manually
    2. How to get the click on a menu item in order to call GoToAsync for it

    Basically the steps I want to have are:

    On Menu click -> FlyoutIsPresented = true (How to get the click?)
    On Menu item click -> GoToAsync & FlyoutIsPresented = false (How to get the menu item click?)

    Any idea how to get those events?

  • JarvanJarvan Member, Xamarin Team Xamurai

    Any idea how to get those events?

    Try to create a custom FlyoutItem and detect the OnPropertyChanged method.

    public class test : FlyoutItem
    {
        protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            base.OnPropertyChanged(propertyName);
        }
    }
    

    Refer to:
    https://forums.xamarin.com/discussion/159752/can-we-override-the-clickevent-for-shell

  • GraverobberGraverobber Member ✭✭✭

    @Jarvan
    Just wanted to let you know I will give it a try soon, I just got some other priorities I have to finish and then I will be back on it :)

    Thank you for your help so far.

  • JarvanJarvan Member, Xamarin Team Xamurai

    Good Luck!

  • GraverobberGraverobber Member ✭✭✭

    Hi,

    Sorry for being quite that long, I was on vacation and not working on it lately.

    I found a way how to close the menu first before loading of the page starts, but it is not a final solution as the loading still takes a lot of time then and is recognisable.
    (the menu closes smoothly now but then you still have the old menu item on the screen, then it load the other one which takes a short time) it just doesn't look correct.

    On iOS everything works smoothly out of the box, it is really disappointing that Android does have this problem...
    still no one has a good workaround for this?

    I'm about to leave the Shell component for the moment and go back to MasterDetailPage...

  • nhadronhadro Member

    @Graverobber , would you be willing to share your work around for now? It's not great, but I really can't afford to go back to MasterDetail at this point and so a work around until they get this resolved will need to work. Thank you very much.

  • GraverobberGraverobber Member ✭✭✭

    @nhadro
    What I finally did was to use Shell only for iOS and MasterDetailPage for Android because the effect was simply not good in Android. If you separate your views and models for the menu correctly than the effort for having the switch is really not more than setting up the Shell and MasterDetailPage and then have a if check in your App class if you're on Android or iOS and show it accordingly.
    If you're interested in my workaround for Android that closed the menu but caused a delay in loading the page, then you have to add to your AppShell class the following method:

            protected async override void OnPropertyChanged([CallerMemberName] string propertyName = null)
            {
                if (propertyName.Equals("CurrentItem") && Device.RuntimePlatform == Device.Android)
                {
                    FlyoutIsPresented = false;
                    await Task.Delay(300);
                }
                base.OnPropertyChanged(propertyName);
            }
    
  • nhadronhadro Member

    Thanks @Graverobber ! Did you have to change the routing approach for Android as well then? Or did you not have to worry about that in your app?

  • GraverobberGraverobber Member ✭✭✭

    As I was still just using Push and Pop and stuff like that instead of the new GoToAsync stuff of Shell I didn't have to worry about that it worked correct for both.

Sign In or Register to comment.