How to show busy indicator on each item until data loaded for that item in SfListView?
SfListView allows to display an activity indicator for an item when its data is being loaded in the background. To achieve this, load both ActivityIndicator and a Button in the same row of a Grid element inside the ItemTemplate of SfListView. Maintain a bool property in your Model class which is bound to their IsVisible property to alter their visibility at run time as like below code snippets.
C#
public class BookInfo : INotifyPropertyChanged { private string bookName; private string bookDescription; public bool isDescriptionVisible; public bool isButtonVisible; public bool isIndicatorVisible; public BookInfo() { } public string BookName { get { return bookName; } set { bookName = value; OnPropertyChanged("BookName"); } } public bool IsDescriptionVisible { get { return isDescriptionVisible; } set { isDescriptionVisible = value; OnPropertyChanged("IsDescriptionVisible"); } } public string BookDescription { get { return bookDescription; } set { bookDescription = value; OnPropertyChanged("BookDescription"); } } public bool IsButtonVisible { get { return isButtonVisible; } set { isButtonVisible = value; OnPropertyChanged("IsButtonVisible"); } } public bool IsIndicatorVisible { get { return isIndicatorVisible; } set { isIndicatorVisible = value; OnPropertyChanged("IsIndicatorVisible"); } } public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string name) { if (this.PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs(name)); } }
Disable the visibility of Description and ActivityIndicator initially while adding items into collection.
C#
public class BookInfoRepository:INotifyPropertyChanged { private ObservableCollection<BookInfo> newBookInfo; public event PropertyChangedEventHandler PropertyChanged; public ObservableCollection<BookInfo> NewBookInfo { get { return newBookInfo; } set { this.newBookInfo = value; } } public void OnPropertyChanged(string name) { if (this.PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs(name)); } public BookInfoRepository() { GenerateNewBookInfo(); } private void GenerateNewBookInfo() { NewBookInfo = new ObservableCollection<BookInfo>(); NewBookInfo.Add(new BookInfo() { BookName = "Machine Learning Using C#", BookDescription = "You’ll learn several different approaches to applying machine learning", IsIndicatorVisible = false, IsButtonVisible = true, IsDescriptionVisible=false }); NewBookInfo.Add(new BookInfo() { BookName = "Object-Oriented Programming in C#", BookDescription = "Object-oriented programming is the de facto programming paradigm", IsIndicatorVisible = false, IsButtonVisible = true, IsDescriptionVisible = false }); NewBookInfo.Add(new BookInfo() { BookName = "C# Code Contracts", BookDescription = "Code Contracts provide a way to convey code assumptions", IsIndicatorVisible = false, IsButtonVisible = true, IsDescriptionVisible = false }); } }
Bind the bool values for the IsVisible properties to switch between indicator and button while loading the description.
XAML
<ContentPage> <ContentPage.BindingContext> <local:BookInfoRepository x:Name="ViewModel" /> </ContentPage.BindingContext> <sync:SfListView x:Name="listView" AutoFitMode="Height" BackgroundColor="#d3d3d3" SelectionMode="None" ItemsSource="{Binding NewBookInfo}"> <sync:SfListView.ItemTemplate> <DataTemplate> <Frame HasShadow="True" Margin="5,5,5,0"> <Grid Padding="5"> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="2*" /> </Grid.RowDefinitions> <Label Text="{Binding BookName}" FontAttributes="Bold" FontSize="19" /> <Button Grid.Row="1" Clicked="Button_Clicked" Text="Load Description" IsVisible="{Binding IsButtonVisible}" HorizontalOptions="Center" VerticalOptions="Center"/> <Label Grid.Row="1" Text="{Binding BookDescription}" FontSize="15" IsVisible="{Binding IsDescriptionVisible}" /> <ActivityIndicator Grid.Row="1" IsEnabled="True" IsRunning="True" IsVisible="{Binding IsIndicatorVisible}" /> </Grid> </Frame> </DataTemplate> </sync:SfListView.ItemTemplate> </sync:SfListView> </ContentPage>
In the Clicked event of the Button, get the row data from its BindingContext and alter the bool values accordingly.
C#
public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); } private async void Button_Clicked(object sender, EventArgs e) { var model = ((sender as Button).BindingContext as BookInfo); model.IsIndicatorVisible = true; model.IsButtonVisible = false; await Task.Delay(2000); model.IsDescriptionVisible = true; model.IsIndicatorVisible = false; } }
Screenshot:
Click here to download the sample.
Conclusion
I hope you enjoyed learning about how to show busy indicator on each item until data loaded for that item in SfListView.
You can refer to our Xamarin.Forms ListView feature tour page to know about its other groundbreaking feature representations. You can also explore our Xamarin.Forms ListView documentation to understand how to create and manipulate data.
For current customers, you can check out our components from the License and Downloads page. If you are new to Syncfusion, you can try our 30-day free trial to check out our other controls.
If you have any queries or require clarifications, please let us know in the comments section below. You can also contact us through our support forums, Direct-Trac, or feedback portal. We are always happy to assist you!