Search code examples
c#popupspinnermauiloading

Show "loading" popup while page is generated


I'm trying to get a popup to appear while the app downloads data from the database and the page is generated/refreshed.

Maybe I lack the knowledge necessary to understand the order in which the instructions are executed or if the problem lies in the incorrect handling of animations.

I call the same popup on different project pages. In some cases it works and in others it is not shown at all.

PopUp.cs

using CommunityToolkit.Maui.Views;

namespace FZ102;

public partial class PopupPageLoading : Popup
{
    public PopupPageLoading()
    {
        InitializeComponent();

    }

    public void Dismiss()
    {
        // End the appearance transition.
        //endAppearanceTransition();

        // Dismiss the popup.
        DismissAsync();
    }

     void DismissAsync()
    {
        this.Close();
    }
}

PopUp xaml

<?xml version="1.0" encoding="utf-8" ?>
<toolkit:Popup
    x:Class="FZ102.PopupPageLoading"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
    Size="300, 300"
    CanBeDismissedByTappingOutsideOfPopup="False">
    <VerticalStackLayout Spacing="5">
        <Image
            Margin="0"
            HeightRequest="300"
            IsAnimationPlaying="True"
            Source="FZ102loading.gif"
            WidthRequest="300" />
    </VerticalStackLayout>
</toolkit:Popup>

Page's call

public void RiempioSettimana(DateTime DP)
{

    PopupPageLoading p = new PopupPageLoading();
    Application.Current.MainPage.ShowPopup(p);


    ModelloAgendaDisponibilita DisponibilitaSettimana = new ModelloAgendaDisponibilita;
    string DateInStriga = "";

    DateInStriga = "20" + L_Lun.Text[^2..] + L_Lun.Text[^5..^3] + L_Lun.Text[^8..^6];
    DisponibilitaSettimana = ScaricoGiorno(DateInStriga);

    if (DisponibilitaSettimana != null)
    {
        if (DisponibilitaSettimana.Stato == "Libero") F_C1R1.BackgroundColor = Color.FromArgb(ColoreLibero);
        else
         if (DisponibilitaSettimana.Stato == "Offerto") F_C1R1.BackgroundColor = Color.FromArgb(ColoreOffertoMaLibero);

    }
    else
    {
        F_C1R1.BackgroundColor = Color.FromArgb(ColoreLibero);
    }
    p.Close();
}


private ModelloAgendaDisponibilita ScaricoGiorno(string DataInStringa)
{
    ModelloAgendaDisponibilita DR = new ModelloAgendaDisponibilita { Stato = "Vuoto" };

    DR = Libreria.EstraggoModelloAgendaDisponibilita(UserNameRicevuto, path, DataInStringa);

    return DR;
}

Connection to DB

public static ModelloAgendaDisponibilita EstraggoModelloAgendaDisponibilita(string UserName, string path, string DataInStringa)
{
    FirestoreDb db = FirestoreDb.CreateAsync("****").Result;
    DocumentReference DocumentoEstratto = db.Collection("***").Document(UserName).Collection(DataInStringa).Document(DataInStringa);
    DocumentSnapshot snap = DocumentoEstratto.GetSnapshotAsync().Result;
    ModelloAgendaDisponibilita DR = snap.ConvertTo<ModelloAgendaDisponibilita>();
    return (DR);
}

(Maybe the fact that it's a synchronous call is a problem?)

thank you.


Solution

  • The easiest is to use ActivityIndicator

    <ActivityIndicator x:Name="loadingIndicator" IsRunning="False" />
    

    And you stop it and start it with loadingIndicator.IsRunning = true;

    To make this more interested you can make a modal page like a popup and show whatever content you like using Navigation.PushModalAsync that pushes a page on top of the stack and as easily you can remove it. Here is an eaxmple:

    var page = new LoadingPage();
    await Navigation.PushModalAsync(page);
    
    await Task.Delay(5000);
    
    await Navigation.PopModalAsync();
    

    LoadingPage

    public class LoadingPage : ContentPage
    {
        public LoadingPage()
        {
            BackgroundColor = Colors.Transparent;
    
            Content = new Grid
            {
                HorizontalOptions = LayoutOptions.Center,
                VerticalOptions = LayoutOptions.Center,
                WidthRequest = 200,
                HeightRequest = 200,
                BackgroundColor = Colors.White,
                Children =
                {
                    new ActivityIndicator
                    {
                        IsRunning = true,
                        VerticalOptions = LayoutOptions.Center,
                        HorizontalOptions = LayoutOptions.Center
                    }
                }
            };
        }
    
        protected override bool OnBackButtonPressed()
        {
            // Prevent the back button from closing the page
            return true;
        }
    }
    

    Update

    I forgot about your freezing problem. Your code left a lot of things to wish for. You need to learn Async/Await and start to use it in about everything. Read about it here Asynchronous programming

    I am not able to test and verify your code in any way so I have updated on what I can see. I have made your methods Async and awaited what I believe needs to be awaited. By doing this you will allow the UI to be responisve and you will not lock up the program like you doing now. Since you know your program better you need to find the bottle necks and await them.

    Here we go.

    public async Task RiempioSettimana(DateTime DP)
    {
        var page = new LoadingPage();
        await Navigation.PushModalAsync(page);
    
    
        ModelloAgendaDisponibilita DisponibilitaSettimana = new ModelloAgendaDisponibilita;
        string DateInStriga = "";
    
        DateInStriga = "20" + L_Lun.Text[^2..] + L_Lun.Text[^5..^3] + L_Lun.Text[^8..^6];
        DisponibilitaSettimana = await ScaricoGiorno(DateInStriga);
    
        if (DisponibilitaSettimana != null)
        {
            if (DisponibilitaSettimana.Stato == "Libero") F_C1R1.BackgroundColor = Color.FromArgb(ColoreLibero);
            else
             if (DisponibilitaSettimana.Stato == "Offerto") F_C1R1.BackgroundColor = Color.FromArgb(ColoreOffertoMaLibero);
    
        }
        else
        {
            F_C1R1.BackgroundColor = Color.FromArgb(ColoreLibero);
        }
        await Navigation.PopModalAsync();
    }
    
    
    private async Task<ModelloAgendaDisponibilita> ScaricoGiorno(string DataInStringa)
    {
        ModelloAgendaDisponibilita DR = new ModelloAgendaDisponibilita { Stato = "Vuoto" };
    
        DR = await Libreria.EstraggoModelloAgendaDisponibilita(UserNameRicevuto, path, DataInStringa);
    
        return DR;
    }
    public static async Task<ModelloAgendaDisponibilita> EstraggoModelloAgendaDisponibilita(string UserName, string path, string DataInStringa)
    {
        FirestoreDb db = await FirestoreDb.CreateAsync("****");
        DocumentReference DocumentoEstratto = await db.Collection("***").Document(UserName).Collection(DataInStringa).Document(DataInStringa);
        DocumentSnapshot snap = await DocumentoEstratto.GetSnapshotAsync();
        ModelloAgendaDisponibilita DR = snap.ConvertTo<ModelloAgendaDisponibilita>();
        return DR;
    }