I would like to show activity indicator while the data is loading. What is the proper way?
When I navigate to this page the loading indicator is not shown at all, during the navigation feels like a little lag such as the loading happens when navigating.
View and ViewModel are registered as transient.
In the ViewModel:
[ObservableProperty]
bool _isBusy;
[ObservableProperty]
string _loadingText;
public ObservableRangeCollection<TestModel> Items { get; set; } = new ObservableRangeCollection<TestModel>();
public TestViewModel(IRepository repository)
{
_repository = repository;
LoadData();
}
private void LoadData()
{
Items.Clear();
Task.Run(async () =>
{
try
{
await MainThread.InvokeOnMainThreadAsync(() =>
{
IsBusy = true;
LoadingText = "Loading...";
});
_allItems = await _repository.GetAllAsync();
Items.AddRange(_allItems );
}
catch (Exception)
{
throw;
}
finally
{
await MainThread.InvokeOnMainThreadAsync(() =>
{
IsBusy = false;
});
}
});
}
In the View:
<CollectionView
IsVisible="{Binding IsBusy, Converter={StaticResource InvertedBoolConverter}}"
ItemsSource="{Binding Items}"
SelectionMode="None">
<CollectionView.ItemTemplate>
<DataTemplate>
<Label Text="{Binding Name)"/>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<VerticalStackLayout IsVisible="{Binding IsBusy}"
HorizontalOptions="Center"
Spacing="6"
VerticalOptions="Center">
<ActivityIndicator
HeightRequest="44"
HorizontalOptions="Center"
IsRunning="{Binding IsBusy}"
Scale="{OnPlatform iOS=1.3,
Android=1.0}"
WidthRequest="44"
Color="{DynamicResource PrimaryColor}" />
<Label
FontSize="14"
HorizontalOptions="Center"
HorizontalTextAlignment="Center"
LineBreakMode="WordWrap"
Text="{Binding LoadingText}"
TextColor="{DynamicResource PrimaryColor}" />
</VerticalStackLayout>
Since you have defined the following variable, but you used variable IsBusy
in .xaml
.
[ObservableProperty]
bool _isBudy;
So,please try to change the defined variable as follows:
[ObservableProperty]
bool _isBusy;
And based on your code, I added some fake data to simulate this problem. But all work properly on my side.
Please refer to the following code:
private void LoadData()
{
Items.Clear();
Task.Run(async () =>
{
try
{
await MainThread.InvokeOnMainThreadAsync(() =>
{
IsBusy = true;
LoadingText = "Loading...";
});
//_allItems = await _repository.GetAllAsync();
// Items.AddRange(_allItems);
//add Task.delay
await Task.Delay(TimeSpan.FromSeconds(2));
// add some fake data here
AddItems();
}
catch (Exception)
{
throw;
}
finally
{
await MainThread.InvokeOnMainThreadAsync(() =>
{
IsBusy = false;
});
}
});
}