AboutContact

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("https://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.

Android add new jar library

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();
		}

	}
	

Android load data from json

You can download the complete example from here.

 

 

Leave a comment








Comments


- 07 October 2017 at 12:41
Such simple thing, I was about to bling.
Yo mama - 17 May 2018 at 21:47
Doesn't f'ing work!
- 02 March 2017 at 00:21
Very nice tutorial. Works great. I am new to android and am wondering how can I convert this to use multiple views with a customer adapter? I want to have a two views. One is a section header every few rows, the other is data. If the data is of a certain type the section header view is populated. Otherwise the data view is populated. Would the changes be made in the list adapter? Thanks.
- 27 October 2016 at 13:01
Very good tutorial. But i just want to click on item, for this example and pass data(item name) to another activity. Thanks for your help
- 12 October 2016 at 10:06
its working sir..but i want to devide one view into two parts vertically.each part am using listviews.so when i click the item in the listview in first part automatically data will be displaed in listview of 2nd part.can you suggest me how to write code for that
Andrea - 19 October 2016 at 21:26
If you want to divide vertically a list view you can use sections. As soon as the app is started and you still haven't touched anything, the number of section is just one, as soon as you click, you can add another section (so at maximum you'll have two sections that will divide vertically your list) and populate it with the data you'll need. Hope that I've understand well your question and hope it will help :-)
- 08 September 2016 at 20:28
hi! Tanks for sample! I create my Json file by a PHP script hosted in http://ggeek.byethost9.com/conVagas.php I edited your sample to access my Json, but dont works. The list view still empty. Any idea for why? Tanks!
Andrea - 09 September 2016 at 20:55
Hi, I've tried your link, but the server you've used requires an javascript enabled browser. This is what I receive: "This site requires Javascript to work, please enable Javascript in your browser or use a browser with Javascript support". For this reason no data are sent to your app!
JOVYLLE - 12 September 2016 at 09:35
You could just echo the json inyour php so no need any javascripting enable thing
Romulo de Oliveira Silva - 12 September 2016 at 20:18
Thanks a lot for the help The problem was solved when stayed the .php files on another server. The server that worked was the 000webhost.com . thank you.
- 01 August 2016 at 03:00
Thank You but how about include picture to the list http://paste.ofcode.org/DCDay7TZ2Z4jCTXdbRwx3
Andrea - 01 September 2016 at 09:37
Hi, thank you for your comment. The pasted link does is not working. Can you please explain me?
- 16 April 2016 at 17:11
Hi, thanks for such a great tutorial. I'm facing a problem. I'm making the ListView in fragment (I've made a few tabs, with fragments). Can't understand where to use the codes in case of populating them in one fragment.
Andrea - 17 April 2016 at 11:21
Hi, thank you for your comment. You can define the functions/classes for downloading the data and the listview adapter in external classes, then download the data and fill the listview adapter inside the fragment itself. Every time the fragment is loaded the data are downloaded too. You can also implement a cache mechanism.
Juan Alberto Bautista Grande - 22 June 2016 at 20:31
Hello, I have the same issue, Could you solve it? if yes, can you help me to do it? Please :(
- 10 November 2015 at 00:54
Hi, Thank you for a very informative tutorial. This has helped me a lot, and I have successfully got the app working. However, I'm trying to populate the list using my own JSON array, but it does not seem to work. My URL = http://localhost/smartpark/get_info.php However all I get is a blank screen. Any help would be greatly appreciated. Thank you, Sahan
Andrea - 10 November 2015 at 20:42
Hi, thank you for your comment. Are you working with the android emulator or with an external device? Use the external ip address (like 192...) an be sure that your local server is accepting connection from outside. Just try to open the browser and open the server url. Hope it helps, in case what for a server are you using?





AboutContactPrivacy