smartsoldier
smartsoldier

Reputation: 153

How to make the loading screen to disappear when my data is loaded in Xamarin Forms?

I want to build a loading screen when no data is displayed. But it's not working, it keeps loading forever. How to make the loading screen to disappear when my data is loaded?

This is my C# code

        if (Clublistview.ItemsSource == null)
        {
            try
            {
                base.OnAppearing();
                await setClubs(Clublistview);

                overlay.IsVisible = false;
                Clublistview.IsVisible = true;
            }
            catch (Exception ex)
            {
                //MessagingCenter
                await DisplayAlert("Error",
                    "There seems to be an error, please check your internet connection.",
                    "OK");
            }
        }
        else
        {
            overlay.IsVisible = true;
            Clublistview.IsVisible = false;
        }

This is the XAML code

 <ListView  x:Name="Clublistview" HasUnevenRows="true" ItemSelected="OnItemSelected" ItemsSource="{Binding Id}" IsVisible="true">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell Height="55">
                            <StackLayout BackgroundColor="White"
                            Orientation="Vertical">
                                <StackLayout Orientation="Horizontal" Padding="2,2,2,2">
                                    <Image Source="{Binding Logo}" IsVisible="true" WidthRequest="50" HeightRequest="50"/>

                                    <StackLayout Orientation="Vertical">
                                        <Label Text="{Binding Name}" FontSize="20" x:Name="BtnClub" 
                                         TextColor="Black" />

                                        <Label HorizontalOptions="Start" Text="Select for more info" FontSize="10"/>
                                        <!--<Button BackgroundColor="White" TextColor="Black"  HorizontalOptions="Start" x:Name="btnInfo" 
                                        Text="Select for more info" FontSize="10" Clicked="OnInfoClicked" CommandParameter="{Binding Id}"/>-->
                                    </StackLayout>
                                </StackLayout>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
            <ContentView x:Name="overlay" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"  AbsoluteLayout.LayoutFlags="All" IsVisible="false">
                <ActivityIndicator  IsRunning="True" IsVisible="True" Color="Black" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"/>
              </ContentView>

Upvotes: 2

Views: 11049

Answers (2)

This is what worked for me:

protected override void OnAppearing()
{
    base.OnAppearing();
            
    this.layoutLoadingSpinner.IsVisible = true;
    this.layoutContent.IsVisible = false;

    // Load slow-loading model on a separate thread
    MySlowLoadingModel model = null;
    await Task.Run(() =>
    {
        model = new MySlowLoadingModel();
    });

    this.BindingContext = model;
    this.layoutLoadingSpinner.IsVisible = false;
    this.layoutContent.IsVisible = true;
}

(Another option that avoids async/await is to call MainThread.BeginInvokeOnMainThread() inside the Task.Run)

An unfortunate side-effect is that any code run on the second thread becomes very difficult to debug. It seems the Xamarin debugger doesn't work right with multiple threads.

Upvotes: 1

therealjohn
therealjohn

Reputation: 2398

It looks like this code is placed on the OnAppearing method of your ContentPage. If that's the case, it's only going to be called 1 time as the page is shown. Assuming that Clublistview.ItemsSource is not null, then this code gets executed:

overlay.IsVisible = true;
Clublistview.IsVisible = false;

This means that your overlay is visible and the ActivityIndicator will be spinning. If this is not in OnAppearing then I am not sure when you are calling the method it is in.

You might want to do something like this instead:

public override async void OnAppearing()
{
   base.OnAppearing();

   // Show your overlay
   overlay.IsVisible = true;
   Clublistview.IsVisible = false;

   // Load the items into the ItemsSource
   await setClubs(Clublistview);

   // Hide the overlay
   overlay.IsVisible = false;
   Clublistview.IsVisible = true;
}

You can achieve this type of behavior in a cleaner way with the MVVM pattern. With MVVM you can use a property binding to control when the overlay is shown. We have some guides on MVVM and Xamarin.Forms that can help get you started here. Here is a blog post that shows an example too.

Upvotes: 5

Related Questions