Xamarin.Forms ListView Data Binding
Contents
Hello, in this post I will show you the construction of Covid-19 application in Xamarin.Forms. First I will get the data from the service and then show this data in ListView.
I will be using this service to pull in Covid-19 data. Here, the number of patients, recovered, deaths, etc. for each country are shown.
Covid-19 Model Class
To properly pull data, a model class is required first. The variable names of this class must be the same as the property names of the JSON file that we will draw. To do this easily, click on the link written above and copy the data. Then go to jsonutils.com and submit it as a C# class.
Right click on the project and add a class named Example.cs
public class Example
{
public string objectIdFieldName { get; set; }
public UniqueIdField uniqueIdField { get; set; }
public string globalIdFieldName { get; set; }
public string geometryType { get; set; }
public SpatialReference spatialReference { get; set; }
public List<Field> fields { get; set; }
public bool exceededTransferLimit { get; set; }
public List<Feature> features { get; set; }
}
public class UniqueIdField
{
public string name { get; set; }
public bool isSystemMaintained { get; set; }
}
public class SpatialReference
{
public int wkid { get; set; }
public int latestWkid { get; set; }
}
public class Field
{
public string name { get; set; }
public string type { get; set; }
public string alias { get; set; }
public string sqlType { get; set; }
public object domain { get; set; }
public object defaultValue { get; set; }
public int? length { get; set; }
}
public class Attributes
{
public int OBJECTID { get; set; }
public string Province_State { get; set; }
public string Country_Region { get; set; }
public object Last_Update { get; set; }
public double? Lat { get; set; }
public double? Long_ { get; set; }
public int Confirmed { get; set; }
public int Recovered { get; set; }
public int Deaths { get; set; }
public int Active { get; set; }
public object Admin2 { get; set; }
public object FIPS { get; set; }
public string Combined_Key { get; set; }
}
public class Feature
{
public Attributes attributes { get; set; }
}
Covid-19 ViewModel Class
BaseViewModel.cs
A BaseViewModel class is required to control the variability of the data. Right click on the project and add a class named BaseViewModel.cs. It inherits INotifyPropertyChanged interface.
public class BaseViewModel : INotifyPropertyChanged
{
private bool _isLoading { get; set; }
public bool IsLoading
{
get
{
return _isLoading;
}
set
{
if (value != _isLoading)
{
_isLoading = value;
NotifyPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
APIViewModel.cs
Now create the APIViewModel.cs class. In this class, Covid-19 data is taken and placed in the List.
Then go to Manage NuGet Packages and download the Newtonsoft.Json plugin. With this plugin, you can easily deserialize the JSON file. In Top 5 Useful Plugins in Xamarin article, I have listed useful plugins.
public class APIViewModel : BaseViewModel
{
private List<Attributes> attributeList { get; set; }
public List<Attributes> attributes
{
get
{
return attributeList;
}
set
{
if (value != attributeList)
{
attributeList = value;
NotifyPropertyChanged();
}
}
}
public APIViewModel()
{
GetDataAsync();
}
string url = "https://services1.arcgis.com/0MSEUqKaxRlEPj5g/arcgis/rest/services/ncov_cases/FeatureServer/1/query?f=json&where=(Confirmed%3E%200)%20OR%20(Deaths%3E0)%20OR%20(Recovered%3E0)&returnGeometry=false&outFields=*&orderByFields=Country_Region%20asc,Province_State%20asc&resultOffset=0&resultRecordCount=250";
private async void GetDataAsync()
{
IsLoading = true;
HttpClient httpClient = new HttpClient();
var response = await httpClient.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
var posts = JsonConvert.DeserializeObject<Example>(content);
List<Attributes> data = new List<Attributes>();
for (int i = 0; i < posts.features.Count; i++)
{
data.Add(new Attributes
{
Country_Region = posts.features[i].attributes.Country_Region,
Confirmed = posts.features[i].attributes.Confirmed,
Recovered = posts.features[i].attributes.Recovered,
Deaths = posts.features[i].attributes.Deaths,
});
}
attributes = data;
}
else
{
Debug.WriteLine("Error when get data!");
}
IsLoading = false;
}
}
Notice that this class inherits the BaseViewModel class.
We will also use the IsLoading bool variable for the ActivityIndicator on the XAML side.
Show Covid-19 Datas in MainPage.xaml
After taking the data and putting them in the List, let’s show them in the ListView that we will create in ContentPage. And with an ActivityIndicator, let’s check if the data is coming in.
There is no need to create a new ContentPage, as the MainPage.xaml page was added while creating the application.
ListView
Create a ListView in MainPage. Instead of typing manually, you can drag and drop from Toolbox. Add a Grid with 2 rows and 3 columns into the <ViewCell> in the <DataTemplate>.
<ListView ItemsSource="{Binding attributes}" RowHeight="75">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Grid>
<Label Text="{Binding Country_Region}" TextColor="#ff1e56" Grid.Row="0" Grid.ColumnSpan="3" Grid.RowSpan="2" HorizontalTextAlignment="Center" FontSize="20"/>
<Label Text="Confirmed" TextColor="#000000" Grid.Row="1" Grid.Column="0" HorizontalTextAlignment="Center"/>
<Label Text="{Binding Confirmed}" TextColor="#706c61" Grid.Row="2" Grid.Column="0" HorizontalTextAlignment="Center"/>
<Label Text="Recovered" TextColor="Black" Grid.Row="1" Grid.Column="1" HorizontalTextAlignment="Center"/>
<Label Text="{Binding Recovered}" TextColor="#706c61" Grid.Row="2" Grid.Column="1" HorizontalTextAlignment="Center"/>
<Label Text="Deaths" TextColor="Black" Grid.Row="1" Grid.Column="2" HorizontalTextAlignment="Center"/>
<Label Text="{Binding Deaths}" TextColor="#706c61" Grid.Row="2" Grid.Column="2" HorizontalTextAlignment="Center"/>
</Grid>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
ActivityIndicator
Now create an ActivityIndicator for control purposes. Bind the IsLoading variable in the ViewModel class to IsRunning and IsVisible here.
<Label Text="Loading..."
IsVisible="{Binding IsLoading}"
TextColor="Blue"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand"/>
<ActivityIndicator
IsRunning="{Binding IsLoading}"
IsVisible="{Binding IsLoading}"
Color="Blue"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"/>
MainPage.xaml will look like this.
<ContentPage.Content>
<StackLayout>
<Label Text="Loading..."
IsVisible="{Binding IsLoading}"
TextColor="Blue"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand"/>
<ActivityIndicator
IsRunning="{Binding IsLoading}"
IsVisible="{Binding IsLoading}"
Color="Blue"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"/>
<ListView ItemsSource="{Binding attributes}" RowHeight="75">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Grid>
<Label Text="{Binding Country_Region}" TextColor="#ff1e56" Grid.Row="0" Grid.ColumnSpan="3" Grid.RowSpan="2" HorizontalTextAlignment="Center" FontSize="20"/>
<Label Text="Confirmed" TextColor="#000000" Grid.Row="1" Grid.Column="0" HorizontalTextAlignment="Center"/>
<Label Text="{Binding Confirmed}" TextColor="#706c61" Grid.Row="2" Grid.Column="0" HorizontalTextAlignment="Center"/>
<Label Text="Recovered" TextColor="Black" Grid.Row="1" Grid.Column="1" HorizontalTextAlignment="Center"/>
<Label Text="{Binding Recovered}" TextColor="#706c61" Grid.Row="2" Grid.Column="1" HorizontalTextAlignment="Center"/>
<Label Text="Deaths" TextColor="Black" Grid.Row="1" Grid.Column="2" HorizontalTextAlignment="Center"/>
<Label Text="{Binding Deaths}" TextColor="#706c61" Grid.Row="2" Grid.Column="2" HorizontalTextAlignment="Center"/>
</Grid>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
Conclusion
When you run the project, a screen like this will appear. You can change the statusBarColor, navigationBarColor etc by playing with the design a little. In Material Theme in Xamarin article I showed you how to do this.