Search code examples
c#androidmauispinner

How do I get my Android Spinner to work correctly


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


Solution

  • 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.