Reputation: 153
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
Reputation: 86015
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
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