ListView.This project load data (JSON) from an URL to parse. Project descriptions:
- Loading JSON data from an URL by using an AsyncTaskand parse it to my own object.
- In ListView, showing only 5 items for first time.
- Using OnScrollListener()forListViewto detect scrolling reach to it's bottom.
- Continue loading data and show in ListView.
Update info
With Material Design technology, 
RecyclerView is the alternate widget for ListView in creating list view/table view now. Please read my newer post if you would like to make an endless RecyclerView with a ProgressBar at the bottom when data is loading...
2. Create an own POJO to use for
ListView item:
CountryInfor.java
3. Custom an package com.blogspot.hongthaiit.androidloadmorelistview;
public class CountryInfor {
 private String id;
 private String name;
 
 public String getId() {
  return id;
 }
 
 public void setId(String id) {
  this.id = id;
 }
 
 public String getName() {
  return name;
 }
 
 public void setName(String name) {
  this.name = name;
 }
}
AsyncTask to downloading data from Internet:
LoadCountriesFromUrlTask.java
4. Create an activity to run:package com.blogspot.hongthaiit.androidloadmorelistview;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.util.Log;
public class LoadCountriesFromUrlTask extends AsyncTask<Void, Void, String> {
 private Activity activity;
 private String url;
 private ProgressDialog dialog;
 private final static String TAG = LoadCountriesFromUrlTask.class.getSimpleName();
 public LoadCountriesFromUrlTask(Activity activity, String url) {
  super();
  this.activity = activity;
  this.url = url;
 }
 @Override
 protected void onPreExecute() {
  super.onPreExecute();
  // Create a progress dialog
  dialog = new ProgressDialog(activity); 
  // Set progress dialog title
  dialog.setTitle("ListView Load More Tutorial");
  // Set progress dialog message
  dialog.setMessage("Loading more...");
  dialog.setIndeterminate(false);
  // Show progress dialog
  dialog.show(); 
 }
 @Override
 protected String doInBackground(Void... params) {
  // call load JSON from url method
  return loadJSON(this.url).toString();
 }
 @Override
 protected void onPostExecute(String result) {
  ((MainActivity) activity).parseJsonResponse(result);
  dialog.dismiss();
  Log.i(TAG, result);
 }
 public JSONObject loadJSON(String url) {
  // Creating JSON Parser instance
  JSONParser jParser = new JSONParser();
  // getting JSON string from URL
  JSONObject json = jParser.getJSONFromUrl(url);
  return json;
 }
 private class JSONParser {
  private InputStream is = null;
  private JSONObject jObj = null;
  private String json = "";
  // constructor
  public JSONParser() {
  }
  public JSONObject getJSONFromUrl(String url) {
   // Making HTTP request
   try {
    // defaultHttpClient
    DefaultHttpClient httpClient = new DefaultHttpClient();
    HttpPost httpPost = new HttpPost(url);
    HttpResponse httpResponse = httpClient.execute(httpPost);
    HttpEntity httpEntity = httpResponse.getEntity();
    is = httpEntity.getContent();
   } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
   } catch (ClientProtocolException e) {
    e.printStackTrace();
   } catch (IOException e) {
    e.printStackTrace();
   }
   try {
    BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"),
      8);
    StringBuilder sb = new StringBuilder();
    String line = null;
    while ((line = reader.readLine()) != null) {
     sb.append(line + "\n");
    }
    is.close();
    json = sb.toString();
   } catch (Exception e) {
    Log.e("Buffer Error", "Error converting result " + e.toString());
   }
   // try parse the string to a JSON object
   try {
    jObj = new JSONObject(json);
   } catch (JSONException e) {
    Log.e("JSON Parser", "Error parsing data " + e.toString());
   }
   // return JSON String
   return jObj;
  }
 }
}
- It's layout simple like this:
activity_main.xml
- In activity programmatically code, we must set <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" >
    <LinearLayout
        android:id="@+id/layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#000055"
        android:orientation="horizontal" >
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/country"
            android:textColor="@android:color/white"
            android:textSize="22sp" />
    </LinearLayout>
    <ListView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/layout"
        android:scrollbars="none" />
</RelativeLayout>
OnScrollListener for the ListView:
private OnScrollListener onScrollListener() {
  return new OnScrollListener() {
   @Override
   public void onScrollStateChanged(AbsListView view, int scrollState) {
    int threshold = 1;
    int count = listView.getCount();
    if (scrollState == SCROLL_STATE_IDLE) {
     if (listView.getLastVisiblePosition() >= count - threshold && pageCount < 2) {
      Log.i(TAG, "loading more data");
      // Execute LoadMoreDataTask AsyncTask
      getDataFromUrl(url_page2);
     }
    }
   }
   @Override
   public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
     int totalItemCount) {
   }
  };
 }
MainActivity.java
5. Layout for each package com.blogspot.hongthaiit.androidloadmorelistview;
import java.util.ArrayList;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.util.Log;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;
public class MainActivity extends Activity {
 private final static String url_page1 = "http://www.json-generator.com/api/json/get/ckDtZPkgJe?indent=2";
 private final static String url_page2 = "http://www.json-generator.com/api/json/get/bVifgkcmxu?indent=2";
 private final static String TAG = MainActivity.class.getSimpleName();
 
 private int pageCount = 0;
 
 private CountryAdapter adapter;
 private ListView listView;
 private ProgressDialog dialog;
 private ArrayList<CountryInfor> countries;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  listView = (ListView) findViewById(R.id.list);
  setListViewAdapter();
  getDataFromUrl(url_page1);
  listView.setOnScrollListener(onScrollListener());
 }
 private void setListViewAdapter() {
  countries = new ArrayList<CountryInfor>();
  adapter = new CountryAdapter(this, R.layout.item_listview, R.id.country_name, countries);
  listView.setAdapter(adapter);
 }
 
 // calling asynctask to get json data from internet
 private void getDataFromUrl(String url) {
  new LoadCountriesFromUrlTask(this, url).execute();
 }
 private OnScrollListener onScrollListener() {
  return new OnScrollListener() {
   @Override
   public void onScrollStateChanged(AbsListView view, int scrollState) {
    int threshold = 1;
    int count = listView.getCount();
    if (scrollState == SCROLL_STATE_IDLE) {
     if (listView.getLastVisiblePosition() >= count - threshold && pageCount < 2) {
      Log.i(TAG, "loading more data");
      // Execute LoadMoreDataTask AsyncTask
      getDataFromUrl(url_page2);
     }
    }
   }
   @Override
   public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
     int totalItemCount) {
   }
  };
 }
 //parsing json after getting from Internet
 public void parseJsonResponse(String result) {
  Log.i(TAG, result);
  pageCount++;
  try {
   JSONObject json = new JSONObject(result);
   JSONArray jArray = new JSONArray(json.getString("message"));
   for (int i = 0; i < jArray.length(); i++) {
    
    JSONObject jObject = jArray.getJSONObject(i);
    CountryInfor country = new CountryInfor();
    country.setId(jObject.getString("id"));
    country.setName(jObject.getString("name"));
    countries.add(country);
   }
   
   adapter.notifyDataSetChanged();
   if (dialog != null) {
    dialog.dismiss();
   }
  } catch (JSONException e) {
   e.printStackTrace();  
  }
 }
}
ListView row:
item_listview.xml
6. Custom a <LinearLayout 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" >
    <TextView
        android:id="@+id/country_name"
        android:layout_width="wrap_content"
        android:layout_height="150dp"
        android:layout_gravity="center"
        android:gravity="center"
        android:drawableLeft="@drawable/earth"
        android:drawablePadding="10dp"
        android:textColor="@android:color/holo_green_dark"
        android:textSize="20sp" />
</LinearLayout>
ListView adapter based on ArrayAdapter:
CountryAdapter.java
7.  Open your AndroidManifest.xml file and add Internet permission:
package com.blogspot.hongthaiit.androidloadmorelistview;
import java.util.List;
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class CountryAdapter extends ArrayAdapter<CountryInfor> {
 private Activity activity;
 public CountryAdapter(Activity activity, int resource, int textViewResourceId,
   List<CountryInfor> countries) {
  super(activity, resource, textViewResourceId, countries);
  this.activity = activity;
 }
 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
  ViewHolder holder = null;
        LayoutInflater inflater = 
                (LayoutInflater) activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        // If holder not exist then locate all view from UI file.
        if (convertView == null) {
            // inflate UI from XML file
            convertView = inflater.inflate(R.layout.item_listview, parent, false);
            // get all UI view
            holder = new ViewHolder(convertView);
            // set tag for holder
            convertView.setTag(holder);
        }  else {
            // if holder created, get tag from view
            holder = (ViewHolder) convertView.getTag();
        }
  
  CountryInfor country = getItem(position);
  
  holder.countryName.setText(country.getName());
  holder.countryName.setCompoundDrawablesWithIntrinsicBounds(R.drawable.earth, 0, 0, 0);
  return convertView;
 }
 private static class ViewHolder {
  private TextView countryName;
  public ViewHolder(View v) {
   countryName = (TextView) v.findViewById(R.id.country_name);
  }
 }
}
AndroidManifest.xml
8. Build and run program, we'll see our result: :D
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.blogspot.hongthaiit.androidloadmorelistview"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="21" />
    
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>
(sorry for ads)
