Android listview: load data from json

You'll learn how to load data from URL in Android, how to define the Android ListView and how to use the JSON format in an Android ListView component. You'll see how to download data from URL in an asynchronous way using a Thread, how to extract the data from the JSON format using a free json library and how to define an adapter for a cutom ListView.

Layout design

Let's create a new Android project.

In the activity_main.xml layout add the Listview component.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/list"
/>

</RelativeLayout>

Create now a new android xml file, call it cell.xml, it will be used for the custom ListView cell definition. Insert two TextView components.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
android:layout_width="wrap_content"
android:layout_height="50dp"
android:id="@+id/name"
android:layout_alignParentStart="true"
android:gravity="center_vertical"
android:paddingStart="10dp"
/>

<TextView
android:layout_width="wrap_content"
android:layout_height="50dp"
android:id="@+id/code"
android:gravity="center_vertical"
android:layout_alignParentEnd="true"
android:paddingEnd="10dp"
/>

</RelativeLayout>

Android: load data from url

Be sure that in  the androidmanifest.xml you've added the internet permission

 Let's now create the class that will download the data in background. Create a new java class, call it Download_data.

On the top, where the class name is defined, be sure to write implements Runnable. This let us to define a custom Runnable class and to perform the background process.

package com.kaleidosstudio.listview_load_data_from_json;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

public class Download_data implements Runnable {

public download_complete caller;

public interface download_complete
{
public void get_data(String data);
}

Download_data(download_complete caller) {
this.caller = caller;
}

private String link;
public void download_data_from_link(String link)
{
this.link = link;
Thread t = new Thread(this);
t.start();
}

public void run() {
threadMsg(download(this.link));
}

private void threadMsg(String msg) {

if (!msg.equals(null) && !msg.equals("")) {
Message msgObj = handler.obtainMessage();
Bundle b = new Bundle();
b.putString("message", msg);
msgObj.setData(b);
handler.sendMessage(msgObj);
}
}


private final Handler handler = new Handler() {

public void handleMessage(Message msg) {

String Response = msg.getData().getString("message");

caller.get_data(Response);

}
};




public static String download(String url) {
URL website;
StringBuilder response = null;
try {
website = new URL(url);

HttpURLConnection connection = (HttpURLConnection) website.openConnection();
connection.setRequestProperty("charset", "utf-8");

BufferedReader in = new BufferedReader(
new InputStreamReader(
connection.getInputStream()));

response = new StringBuilder();
String inputLine;

while ((inputLine = in.readLine()) != null)
response.append(inputLine);

in.close();

} catch (Exception e) {
return "";
}


return response.toString();
}


}


The Download_data class defines:

the download_data_from_link function that has as an input the link to download and start the background process, the download function that downloads the data from an url that returns the response data itself as a string and the run process that is the default function of a runnable class. Moreover, the Download_data has a constructor that allows to define the caller class and an interface that lets the background process to call the caller class as soon as the data have been downloaded from the url.

ListView Adapter

Let's define now the adapter class for the android ListView. This class lets us to define the custom cell for the List.

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class ListAdapter extends BaseAdapter {

MainActivity main;

ListAdapter(MainActivity main)
{
this.main = main;
}

@Override
public int getCount() {
return main.countries.size();
}

@Override
public Object getItem(int position) {
return null;
}

@Override
public long getItemId(int position) {
return 0;
}

static class ViewHolderItem {
TextView name;
TextView code;
}

@Override
public View getView(int position, View convertView, ViewGroup parent){
ViewHolderItem holder = new ViewHolderItem();
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) main.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.cell, null);

holder.name = (TextView) convertView.findViewById(R.id.name);
holder.code = (TextView) convertView.findViewById(R.id.code);

convertView.setTag(holder);
}
else
{
holder = (ViewHolderItem) convertView.getTag();
}


holder.name.setText(this.main.countries.get(position).name);
holder.code.setText(this.main.countries.get(position).code);

return convertView;
}

}

MainActivity definition and structure definition

import java.util.ArrayList;

import com.kaleidosstudio.listview_load_data_from_json.Download_data.download_complete;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;

public class MainActivity extends Activity implements download_complete {

public ListView list;
public ArrayList<Countries> countries = new ArrayList<Countries>();
public ListAdapter adapter;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

list = (ListView) findViewById(R.id.list);
adapter = new ListAdapter(this);
list.setAdapter(adapter);

Download_data download_data = new Download_data((download_complete) this);
download_data.download_data_from_link("http://www.kaleidosblog.com/tutorial/tutorial.json");

}



public void get_data(String data)
{

}


}

The MainActivity is the class that will call the download_data method and will then wait for the data as soon as they are ready. This class will implement the get_data method of the interface download_complete.

Create a new class, call it Countries.java. This class lets us to define the structure where to save the JSON extracted data.

public class Countries {
  String name;
  String code;
}

 

Android Json Listview: let's get the data

In order to perform the Json data extraction, I've used the java-json.jar library. This is a free library that allows you to do a lot of operations with the JSON format. Be sure that in you project you already have the lib folder. Copy inside it the java-json.jar file. You can download it from here. Right click on your project in order to access to the properties. Go to the Java Build Path section. Under libraries select add jar e add the java-json.jar file you've previously added. In the order and export tab be sure that the java-json library is checked.

Let's now to perform the JSON data extraction. JSON is a format that allows to send object through a data serialization.

The main JSON types are: Array, Object.

The array are defined by the [...] parenthesis while the Object are defined by the {...} parenthesis.

In this example I've provided for you a simple JSON data structure composed by an array of objects. You can find this JSON data right here.

As you can seee the structure is the following:

Array[0....N]
 { country ; code }

Let's complete now the get_data interface function, called  as soon as the data are ready.

public void get_data(String data)
{

try {
JSONArray data_array=new JSONArray(data);

for (int i = 0 ; i < data_array.length() ; i++)
{
JSONObject obj=new JSONObject(data_array.get(i).toString());

Countries add=new Countries();
add.name = obj.getString("country");
add.code = obj.getString("code");

countries.add(add);

}

adapter.notifyDataSetChanged();

} catch (JSONException e) {
e.printStackTrace();
}

}

You can download the complete example from here.