Codementor Events

Xamarin.Forms: JSON Data to a ListView(Android & IOS).

Published Sep 13, 2017Last updated Aug 23, 2018
Xamarin.Forms: JSON Data to a ListView(Android & IOS).

Have you ever imagined developing three apps once on android,IOS and windows once ? Well, follow this simple series and enjoy without having worry about developing each platform app seperatly šŸ˜Ž!

Today we are going to make a simple application with a list of items with offline capability in Xamarin.Forms.

Introduction & Requirements

Xamarin.Forms is an API that enables us to quickly build native apps for iOS, Android, and Windows completely in C#. Here are the requirements before we dig in:

  1. Mac System Requirements
    You can use Visual Studio in Mac to develop Xamarin.Forms apps on OS X El Capitan (10.11) or any other newer versions. To develop iOS apps, I recomended at least having the iOS 10 SDK and Xcode 8 installed.
    Note that Windows apps cannot be developed on macOS.

  2. Windows System Requirements.
    Xamarin.Forms apps for iOS and Android can be built on any Windows installation that supports Xamarin development. This requires Visual Studio 2013 Update 2 or newer versions running on Windows 7 or higher. A networked Mac is required for iOS development.

There are some additional requirements for the following types of Windows apps:

  1. Universal Windows Platform (UWP):

    • Windows 10
    • Visual Studio 2015 or newer
    • Universal Windows Developer Tools

    UWP projects are included in Xamarin.Forms solutions created in Visual Studio 2015 and Visual Studio 2017. You can also add a Universal Windows Platform (UWP) App to an existing Xamarin.Forms solution.

  2. Windows 8.1 and Windows Phone 8.1 WinRT:

    • Windows 8.1
    • Visual Studio 2013 Update 2 or newer.

After meeting all these requirements, itā€™s time to get our hands dirty! I will be using Visual Studio 2017.

Letā€™s dive into the code!

STEP 1:

Go to File > New > Project > Cross Platform > Cross Platform App (Xamarin.Forms or Native).

1_image.png

Then check Xamrin.Forms and Shared Project and click Ok.

STEP2:

Install the following Nuget Packages .

In order to install them, right click on Project > Manage Nuget Packages for the solution > Browse):

  1. Newtonsoft.Json
  2. SQLite.Net.Async-PCL
  3. SQLite.Net.Core-PCL
  4. Xam.Plugin.Connectivity.
  5. Microsoft.Net.Http

STEP 3:

This is the URL which contains the JSON data. Click it to view the data.

Now if you notice the data has 5 objects namely :
i).image.
ii).title.
iii).artist
iv).thumbnail_image
v).url

So with the Help of json2csharp site, it can help you to generate C# code out of JSON to create an Object/Model Class.
use this link to it JSON to C#

Now we have to create our Object/Model Class. Letā€™s call it Items.cs
:

using System;
using System.Collections.Generic;
using System.Text;

namespace MySimpleList
{
    class Items
    {
        
        public string image { get; set; }
        public string title { get; set; }
        public string artist { get; set; }
        public string thumbnail_image { get; set; }
        public string url { get; set; }
    }
}


STEP 4 :

Now since we are going to make an Internet/ Http Request we need to provide permissions in our project.

In android:
We need to go the MySimpleList.Android and we navigate to Properties>AndroidManifest.xml and you add this internet permission.

<uses-permission android:name="android.permission.INTERNET" />.

In IOS:
You go to MySimpleList.IOS then info.plist and add the following in the source code.

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key><true/>
</dict>

for more information you can visit this page and research more .

STEP 5

Here we are going to ask for an Http Request which will come with JSON data, after that then we deserialize the data and we attach or bind the data to our ListView. Here in Xamarin.Forms no need of sweating too much, this action is done in few steps.

Below is the MainPage.xaml.cs class

using Newtonsoft.Json;
using Plugin.Connectivity;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace MySimpleList
{
  public partial class MainPage : ContentPage
  {

        public int Count = 0;
        public short Counter = 0;
        public int SlidePosition = 0;
        string heightList;
        int heightRowsList = 90;
        private const string Url = "http://rallycoding.herokuapp.com/api/music_albums";
        // This handles the Web data request
        private HttpClient _client = new HttpClient();
        public MainPage()
    {
      InitializeComponent();
            // We call the OnGetList from Here 
            OnGetList();
    }


        protected async void OnGetList()
        {
            if (CrossConnectivity.Current.IsConnected)
            {

                try
                {
                    //Activity indicator visibility on
                    activity_indicator.IsRunning = true;
                    //Getting JSON data from the Web
                    var content = await _client.GetStringAsync(Url);
                    //We deserialize the JSON data from this line
                    var tr = JsonConvert.DeserializeObject<List<Items>>(content);
                    //After deserializing , we store our data in the List called ObservableCollection
                    ObservableCollection<Items> trends = new ObservableCollection<Items>(tr);

                    //Then finally we attach the List to the ListView. Seems Simple :)
                    myList.ItemsSource = trends;

              
                    //We check the number of Items in the Observable Collection
                    int i = trends.Count;
                    if (i > 0)
                    {
                        //If they are greater than Zero we stop the activity indicator
                        activity_indicator.IsRunning = false;
                    }

                    //Here we Wrap  the size of the ListView according to the number of Items which have been retrieved 
                    i = (trends.Count * heightRowsList);
                    activity_indicator.HeightRequest = i;

                }
                catch (Exception ey)
                {
                    Debug.WriteLine("" + ey);
                }

            }

        }

    }
}

STEP 6:

Open MainPage.xml and to Edit it.

Now, in order to make a list of items, we need a ListView and an activity indicator which shows that data is loading in the ListView.

Let's put this in our code:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MySimpleList"
             x:Class="MySimpleList.MainPage">


    <!-- Activity Indicator-->
    <ActivityIndicator VerticalOptions="Center" HorizontalOptions="Center" x:Name="activity_indicator" Color="#4D7EE1" />
    <!-- ListView-->
    <ListView x:Name="myList" HasUnevenRows="true">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <!-- Here we make a Horizontal orientation with the help of StackLayout-->
                    <StackLayout Orientation="Horizontal" Margin="5" HeightRequest="90">
                        <Image Source="{Binding image}" WidthRequest="100" HeightRequest="200" Aspect="AspectFit" />
                        <StackLayout VerticalOptions="Center">
                            <Label Text="{Binding title}" TextColor="#1C5AD8" />
                        </StackLayout>
                        <Image HorizontalOptions="EndAndExpand" HeightRequest="20" WidthRequest="20" Source="more_icon.png" />
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

</ContentPage>

If you look closely at the code above, it may look a bit weird. Don't worry, let's go through the explanation step-by-step!

I have inserted a ListView, and inside it, I attempted to bind it with data. All you have to know is that if you want a customized binded list in Xamarin.forms, you have to include the following in the ListView:

<ListView.ItemTemplate>,<DataTemplate>,<ViewCell>

It should be clearer to you that I have binded a "Label" with an "Image" instead the StackLayout in my code. This provides a horizontal orienatation. With that said, the "Image" has another stackLayout which gives it a vertical orientation, which will style our list nicely.

So that's how you can make a simple List Application on both IOS, Windows and Android.

Hope this post was clear! Feel free to leave a comment if you have any questions!

Discover and read more posts from Lutaaya Huzaifah Idris
get started
post commentsBe the first to share your opinion
Tanulata Shimpi
5 years ago

Hi

I tried above solution but I donā€™t know when it come to below line
var content = await httpclient.GetStringAsync(Url);
cursor return to main page

no error trap

please help me.

Lutaaya Huzaifah Idris
5 years ago

That line is the one which is responsible for making an asynchronuos request to the server.
Let me hope I have answered you.

Tanulata Shimpi
5 years ago

Hi,

sorry but I was asking that when my cursor reached on that line ā€œvar content = await httpclient.GetStringAsync(Url);ā€ and I pressed key F10 / F11 it return to main method, no error getting, I donā€™t know what was a issue.

please see my below code and guide me if something I missed out. (I already allow Internet permission to my app)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

//below reference for jason
using Newtonsoft.Json.Linq;
using System.IO;
using Plugin.Connectivity;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Net.Http;
using Newtonsoft.Json;

public partial class Branches : ContentPage
{
private string Url = ā€œhttp://rallycoding.herokuapp.com/api/music_albumsā€;

codeā€¦ ā€¦
ā€¦

private async void read_File()
{
int Count = 0;
short Counter = 0;
int SlidePosition = 0;
string heightList;
int heightRowsList = 90;

        HttpClient httpclient = new HttpClient();

        if (CrossConnectivity.Current.IsConnected)
            {
            try
            {
                activity_indicator.IsRunning = true;
                 
                var content = await httpclient.GetStringAsync(Url); // my comment this line getting error [ not moving to next line, even not trapping error in try catch]

                var tr = JsonConvert.DeserializeObject<List<clsBranch>>(content.ToString());
                ObservableCollection<clsBranch> trends = new ObservableCollection<clsBranch>(tr);
                lstbranch.ItemsSource = trends;
                int i = trends.Count;
                if (i > 0)
                {
                   activity_indicator.IsRunning = false;
                }

                i = (trends.Count* heightRowsList);
                activity_indicator.HeightRequest = i;
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine(e.ToString());

            }
        }


    }

}

abhishek sharma
6 years ago

Hi Lutaaya
I am getting error in vs 17 in Mac
HttpClient _client = new HttpClient();
/Users/apple/Projects/jsondemo/jsondemo/MainPage.xaml.cs(9,9): Error CS0246: The type or namespace name ā€˜HttpClientā€™ could not be found (are you missing a using directive or an assembly reference?) (CS0246) (jsondemo.iOS)

Cameron
6 years ago

Hi Lutaaya,
I followed your directions to a T, unfortunately I have a problem that I need help solving.
I am following your directions in order to obtain information from the Google Places API, the problem is that when I use your directions it tells me

"the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly"

No big deal, I simply thought that taking out the List from

var tr = JsonConvert.DeserializeObject<List<PlacesAPI>>(content);

making it into:

var tr = JsonConvert.DeserializeObject<PlacesAPI>(content);

would do the trickā€¦which it didā€¦ sort ofā€¦ I now need to know how to go about passing the information (more specifically, the name variable found in my Result class (seen below)) to my UI. Here is the classes I am working with:

public class Result
    {
        public Geometry geometry { get; set; }
        public string icon { get; set; }
        public string id { get; set; }
        public string name { get; set; }
        public OpeningHours opening_hours { get; set; }
        public IList<Photo> photos { get; set; }
        public string place_id { get; set; }
        public PlusCode plus_code { get; set; }
        public double rating { get; set; }
        public string reference { get; set; }
        public string scope { get; set; }
        public IList<string> types { get; set; }
        public string vicinity { get; set; }
    }

    public class PlacesAPI
    {
        public IList<object> html_attributions { get; set; }
        public IList<Result> results { get; set; }
        public string status { get; set; }
    }

Any help you could give me would be greatly appreciated as I have been trying to solve this problem since 10AMā€¦ itā€™s now 7:15PMā€¦ the headache is real.

Lutaaya Huzaifah Idris
6 years ago

Hello @Cameron thanks so much for reading my blog post, regarding your Issue on how to retrieve that data in UI,
try following this page :
https://stackoverflow.com/questions/23194590/getting-values-of-items-in-ilist

It will give you a headshot, if you get any problem we can discuss more on telegram , my number is +256704594180

Show more replies