My Life with Android
Introduction Android Componets UserInterface Advanced UI Data Storage Advanced Concepts Others New Studio

Android Adapters

Android Adapter is a bridge between the View (e.g. ListView) and the underlying data for that view. An adapter manages the data and adapts the data to the individual rows (listItems) of the view.We bind the adapter with Android listview via setAdapter method. Now, Let us see how adapter works with the help of the following image.

An adapter extends the BaseAdapter class.The adapter would inflate the layout for each row in its getView() method and assign the data to the individual views in the row.The adapter is assigned to the ListView via the setAdapter method on the ListView object.
Tip : Adapters are not only used by ListView, but also by other views which extend AdapterView as, for example, Spinner, GridView, Gallery.
1. Without Adapters, to implement the ListView functionality, you will need to:
  • Create a TextView within a ScrollView group.
  • Then you will have to implement pagination concept for the contents of the TextView.
  • You will also have to write additional code to identify the click event on a particular row in the TextView.
Quite cumbersome job! Isn't it?
2. You may be asking why we need Pagination?
Imagine that you are creating an application that needs to display all your emails and the user will be able to scroll through them. I get around 100 emails on a daily basis and even if we consider 10 emails per day, the email data is going to be extremely huge. If you do not implement pagination, you will have major performance issues in retrieving all that data and showing it on the mobile screen.

To overcome above issue, adapters came into existance.
Let us now understand the internal working of an Android Adapter and how it acts as a data pump to the adapter view. Default platform adapter
Android provides default adapter implementations; the most important are ArrayAdapter and CursorAdapter. ArrayAdapter can handle data based on Arrays or java.util.List. SimpleCursorAdapter can handle database related data.
Let us now understand the internal working of an Android Adapter and how it acts as a data pump to the adapter view.
Adapters call the getView() method which returns a view for each item within the adapter view. The layout format and the corresponding data for an item within the adapter view is set in the getView() method.
Now, it will be a performance nightmare if getView() returns a new View every time it is called. Creating a new view is very expensive in Android as you will need to loop through the view hierarchy (using the find ViewbyID () method) and then inflate the view to finally display it on the screen.It also puts a lot of pressure on the garbage collector. That is because when the user is scrolling through the list, if a new view is created; the old view (since it is not recycled) is not referenced and becomes a candidate to be picked up by the garbage collector. So what Android does is that it recycles the views and reuses the view that goes out of focus.
Below is a visual representation of this recycle process:

In the above figure, let us assume we are displaying the months in a year in a ListView. To begin with, the months January till May are shown in the screen. When you scroll the view, the month January goes out of the display area of the mobile screen. As soon as the January view goes out of the screen, the Adapter View (ListView in this case) sends the view to something called a recycler.So when you scroll up, the getView () method is called to get the next view (which is June). This method getView() has a parameter called convertview which points to the unused view in the recycler. Through the convertview, the Adapter tries to get hold of the unused view and reuse it to display the new view (which is June in this case).

Android ListView

  • Android ListView is a view which groups several items and display them in vertical scrollable list.
  • The list items are automatically inserted to the list using an Adapter that pulls content from a source such as an array or database.


activity_list_view.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
 
<ListView android:id="@+id/list" android:layout_height="wrap_content" android:layout_width="match_parent"> </ListView>
</LinearLayout>
MainActivity.java

package com.example.androidcollegeppt;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.ListView;
import android.widget.Toast; public class ListViewAndroidExample extends Activity { ListView list; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list_view);
// Step 1: list= (ListView) findViewById(R.id.list);
// Step 2: Defined Array values to show in ListView String[] values = new String[] { "Android", "iPhone", "WindowsMobile", "Blackberry", "WebOS", "Ubuntu", "Windows7", "Max OS X" };
// Step 3: Prepare Adapter ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, android.R.id.text1, values);
// Step 4: Assign adapter to ListView list.setAdapter(adapter);
// Step 5: ListView Item Click Listener list.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Step 6: ListView Clicked item value String itemValue = (String) listView.getItemAtPosition(position);
// Step 7 : Show Alert Toast.makeText(getApplicationContext(),"Position :"+position+" ListItem : " +itemValue , Toast.LENGTH_LONG) .show();
} });
} }
Explanation:
// Step 3: Prepare Adapter
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, android.R.id.text1, values);
Adapters are used to provide the data to the ListView

Parameters:
this : // First parameter - Context
simple_list_item_1 : Android internal layout view. // Second parameter - Layout for the row
android.R.id.text1 : In Android internal layout view already defined text fields to show data. //Third parameter - ID of the TextView to which the data is written
values : User defined data array. // Forth - the Array of data

Android CustomAdapter

Custom Adapters
  • Adapters call the getView() method which returns a view for each item within the adapter view.
  • The layout format and the corresponding data for an item within the adapter view is set in the getView() method.
  • When the user is scrolling through the list, if a new view is created; the old view (since it is not recycled) is not referenced.

Example


Step 1 : custom_listview.xml

<?xml version="1.0" encoding="utf-8"?>
<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"
    android:orientation="vertical">

    <ListView
        android:id="@+id/listView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </ListView>

</LinearLayout>

Step 2 : row_custom_list.xml

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

    <ImageView
        android:id="@+id/imageView1"
        android:layout_gravity="center"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:src="@drawable/ic_launcher" />

    <TextView
        android:id="@+id/textView1"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="25dp"
        android:text="TextView" />

</LinearLayout>

Step 3 : CustomListviewDemo.java

package com.example.androidex2;

import com.squareup.picasso.Picasso;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class ListviewDemo extends Activity{
	ListView lv;
	String movie_title[]={"Kabali","Gabarsingh","Srimanthudu","Bahubali","A aa"};
	String img_urls[]={"http://bytecodetechnosolutions.com/Images/kabali.jpg","http://bytecodetechnosolutions.com/Images/gabarsingh.jpg","http://bytecodetechnosolutions.com/Images/srimanthudu.jpg","http://bytecodetechnosolutions.com/Images/bahubali.jpg","http://bytecodetechnosolutions.com/Images/a_aa.jpg"};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.list_view_demo);
		lv=(ListView)findViewById(R.id.lv);
		
lv.setAdapter(new CustomAdapter());
lv.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view,int position, long id) { Toast.makeText(getApplicationContext(), movie_title[position], Toast.LENGTH_SHORT).show(); } });
}
private static LayoutInflater inflater=null; public class CustomAdapter extends BaseAdapter{ public CustomAdapter() { inflater = ( LayoutInflater )ListviewDemo.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public int getCount() { return img_urls.length; } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { if(convertView==null){ convertView = inflater.inflate(R.layout.row_custom_list, null); } TextView tv=(TextView) convertView.findViewById(R.id.textView1); ImageView img=(ImageView) convertView.findViewById(R.id.imageView1); Picasso.with(ListviewDemo.this).load(img_urls[position]).into(img); tv.setText(movie_title[position]); return convertView; } }
}
Picasso Lib

Android ListView with Volley Lib

Download Volley (for retriving data from server)
Download Picasso (for displaying image)

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

    <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:divider="#F00"
        android:dividerHeight="1dp" >
    </ListView>

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

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_gravity="center"
        android:src="@drawable/ic_launcher" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="TextView"
        android:textColor="#F00"
        android:textSize="25dp" />

</LinearLayout>
AndroidManifeast.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
VollyDemo1.Java
package com.example.androidcollegeppt;

import java.util.ArrayList;
import java.util.HashMap;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.squareup.picasso.Picasso;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class VollyDemo1 extends Activity {
	ListView lv;
	Context context;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.custom_listview);
		context=this;
		lv=(ListView) findViewById(R.id.listView);
		getDataFromServer();//Step -1
		
	}
	private void getDataFromServer(){//Using Volley Lib.(Step -1)
		String url = "http://bytecodetechnosolutions.com/TeluguMovies/OnlineMovie_Index.php";
		// Request a string response
		StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
			@Override
			public void onResponse(String response) {
				parseServerJsonData(response);
			}
		}, new Response.ErrorListener() {
			@Override
			public void onErrorResponse(VolleyError error) {

			}
		});
		// Add the request to the queue
		Volley.newRequestQueue(this).add(stringRequest);
	}
	
	ArrayList<HashMap<String, String>> mMovieLists=new ArrayList<HashMap<String, String>>();
	
	private void parseServerJsonData(String response){//Step -2
		HashMap<String, String> hm;
		try {
			JSONObject json= new JSONObject(response);
			JSONArray jArray =json.getJSONArray("items");
			JSONObject jObj;
			for (int i = 0; i < jArray.length(); i++) {
				jObj = jArray.getJSONObject(i);
				 hm=new HashMap<String, String>();
				 hm.put("title", jObj.getString("title"));
				 hm.put("url", jObj.getString("url"));
				 mMovieLists.add(hm);
			}
			lv.setAdapter(new CustomAdapter(this, mMovieLists));//Step -4
		} catch (JSONException e) {}
	}
	private static LayoutInflater inflater=null;
	public class CustomAdapter extends BaseAdapter{   //Step -3
	
		Context context;
		ArrayList<HashMap<String, String>> alData1;
		public CustomAdapter(Context mainActivity, ArrayList<HashMap<String, String>> al) {
			alData1=al;
			context=mainActivity;
			inflater = ( LayoutInflater )context. getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		}
		@Override
		public int getCount() {
			return alData1.size();
		}

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

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

		
		@Override
		public View getView(final int position, View convertView, ViewGroup parent) {
			if(convertView==null){
				convertView = inflater.inflate(R.layout.row_custom_list, null);
			}
			HashMap<String, String> hm=alData1.get(position);
			TextView tv=(TextView) convertView.findViewById(R.id.textView1);
			ImageView img=(ImageView) convertView.findViewById(R.id.imageView1);
			Picasso.with(context).load(hm.get("url")).into(img);
			tv.setText(hm.get("title"));
			convertView.setOnClickListener(new OnClickListener() {            
				@Override
				public void onClick(View v) {
					Toast.makeText(context, "You Clicked ", Toast.LENGTH_LONG).show();
				}
			});   
			return convertView;
		}
	}
}
LayoutInflater : This class is used to instantiate layout XML file into its corresponding View objects.
getLayoutInflater() or getSystemService(String) is used to retrieve a standard LayoutInflater instance that is already hooked up to the current context.

PHP Example

<?php
            $hostname = "mysql1.000webhost.com";
            $username = "a9901961_raju";
            $dbname = "a9901961_raju";
            $password = "admin123";
            $usertable = "user";
    
            $con=mysql_connect($hostname, $username, $password) OR DIE ("Unable to connect to database! Please try again later.");
            mysql_select_db($dbname);

            $query = "SELECT * FROM $usertable;";

            $retval = mysql_query($query);
            if(! $retval )
              {
                echo 'No data'.mysql_error();
              }else{
                $rows = array();

                  while($row = mysql_fetch_assoc($retval)) {
                       $rows[] = array('uname' => $row['uname'], 'upwd' => $row['upwd']);
                  }
             echo json_encode(array('items'=>$rows));
             }

?>

JSON

JSON stands for JavaScript Object Notation.It is an independent data exchange format and is the best alternative for XML.

Android provides four different classes to manipulate JSON data. These classes are JSONArray,JSONObject,JSONStringer and JSONTokenizer.

JSON - Parsing

For parsing a JSON object, we will create an object of class JSONObject and specify a string containing JSON data to it. Its syntax is:

{
  "Employee" :[
         {
            "id":"01",
            "name":"Gopal Varma",
            "salary":"500000"
         },
         {
            "id":"02",
            "name":"Sairamkrishna",
            "salary":"500000"
         },
         {
            "id":"03",
            "name":"Sathish kallakuri",
            "salary":"600000"
         }
   ]
}
String in; JSONObject reader = new JSONObject(in);
The last step is to parse the JSON. An JSON file consist of different object with different key/value pair e.t.c. So JSONObject has a separate function for parsing each of the component of JSON file.
The method getJSONObject returns the JSON object. The method getString returns the string value of the specified key.