How do I get my Android Spinner to work correctly

80 Views Asked by At

Per something I found on the internet I have created a SpinnerPopup to display a spinner for long running tasks. The spinner is there and will come up eventually, but not when I want it to pretty much. All I really want to do is start the spinner when a method starts and end it when the method finishes, but it is far from working. Here is my spinner class;

<toolkit:Popup
x:Class="MauiFirstApp.SpinnerPopup"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:ViewModel="clr-namespace:MauiFirstApp.ViewModels"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit">
<VerticalStackLayout>
    <ActivityIndicator IsRunning="True" />
        <Label Text="Loading..." />
    </VerticalStackLayout>
</toolkit:Popup> 

Here is the code behind;

public partial class SpinnerPopup : Popup
{
    public SpinnerPopup()
    {
        InitializeComponent();
    }
}

Here is the code where I am opening it before the method call and closing it after but it doesn't work at all. It finally opens when the method ends and then closes immediately so nothing is shows, unless I mess around with the code to make is show.

else if (DeviceInfo.Platform.ToString() == Device.Android)
{
    popup = new SpinnerPopup();
    this.ShowPopup(popup);

    await UpdateCarsProperties(id, radio, toggled);         
    await ucvm.GetDisplayData("UpdateCars", cv, popup);

    await popup.CloseAsync();
    popup.Reset();

    Preferences.Set("Updated", true);

}

Not really sure what to do here, the spinner iOS spinner coded above this works for iOS just fine, but not the Android. Any help would be much appreciated.

EDIT: Since the radiochange event fires twice, I have added code in there to start the spinner on the first entry to the method and then stop the spinner on the second entry to the method, but while it starts, it does not end... ever.

if (count == 1)
{
    popup = new SpinnerPopup();
    this.ShowPopup(popup);
    await Task.Delay(50);
}

UpdateCarsProperties(id, radio, toggled);                        
ucvm.GetDisplayData("UpdateCars", cv);

if (count == 2)
{                            
    await popup.CloseAsync();
    popup.Reset();
}

Another thing, it only seems to start the spinner once it has completed the 2 methods between the stop and start, I don't understand this, it should start right away, right? Oh, and a 3rd thing even thought I can see the methods taking a long time, the spinner will not show until I put the task delay in there after the ShowPopup. It is all very confusing to me. Any help would be much appreciated. Thanks

2

There are 2 best solutions below

0
Steve H On BEST ANSWER

I was finally able to get it working. I have this method,

private async void RadioButton_CheckedChanged(object sender, CheckedChangedEventArgs e)

As this method fired twice on a radio button click I added code this way to handle the spinner;

if (DeviceInfo.Platform.ToString() == Device.Android)
{
    if (count == 1)
    {
        popup = new SpinnerPopup();
        this.ShowPopup(popup);                            
    }

    if (count == 2)
    {
        UpdateCarsProperties(id, radio, toggled);
        ucvm.GetDisplayData("UpdateCars", cv);
        await Task.Delay(250);
        await popup.CloseAsync();
        popup.Reset();
    }

    ++count;
    if (count > 2) { count = 1;  }
    Preferences.Set("Count", count);
}

So now when it first comes into the event handler, it starts the spinner then it doesn't stop it until both methods are complete which happens on the second time we come into the method. As you can see, I had to add an Task.Delay which is weird to me, but it now works. I would like to further understand why this works this way is someone wants to shed some light that would be great. Thanks to all the contributed.

2
Jessie Zhang -MSFT On

If you execute a very short code or a task that takes a short time, the SpinnerPopup will show up and disappear very quickly, creating the illusion that it never shows up.

But if you perform a time-consuming task, the SpinnerPopup will show up and disappear when the task is over.

Based on your code, I created a demo and tried to use await Task.Delay(3000); to simulate a time-consuming task, and the result was that the SpinnerPopup could show up and disappear after 3s on android platform.

       var  popup = new SpinnerPopup();
        this.ShowPopup(popup);
        
       //add Task.Delay method here
        await Task.Delay(3000);

        await popup.CloseAsync();
        popup.Reset();