ListView, ListActivity and Custom Adapter in Android


ListView 

A view that shows items in a vertically scrolling list. The items come from the ListAdapter associated with this view.

ListAdapter defines layout for individual row of the list and provide data to the ListView via setAdapter() method of ListView.

Android provides several standard adapters; the most important are ArrayAdapter and CursorAdapter.

ArrayAdapter can handle data based on Arrays or Lists while SimpleCursorAdapter handle database related data.
In this example ArrayAdapter is used, ArrayAdapter  provide constructor with four parameters to construct an ArrayAdapter

For Example:

ArrayAdapter(this, android.R.layout.simple_list_item_1,  android.R.id.text1,  name);

Explanation of arguments:

First parameter    : The current Context
Second parameter   : ID for a row layout to use when instantiating views
Third parameter -  : The id of the TextView within the layout resource to be populated
Forth parameter    : the Array or list of data
 
 
Android provides some standard row layout . These are defined in the R.layout class, and have names such as simple_list_item_1, simple_list_item_2, and two_line_list_item

The id of the TextView within this layout is android.R.id.text1, android.R.id.text2. If nothing is specified the adapter use the android.R.id.text1 ID as default id of the Textview to which the data is written.
In below Example a  layout file conation a ListView and An Activity class try to populate elements from an array to this view
UI Output

                                             
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
   
    <ListView android:id="@+id/mylist"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
               android:background="#aa0000"
               android:layout_weight="1"
               android:drawSelectorOnTop="false"/>
   

</LinearLayout>    

SimpleListActivity.java
                                                             
package org.nk;

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 SimpleListActivity extends Activity {
             String[] name;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        ListView listView = (ListView) findViewById(R.id.mylist);
        name = new String[] { "Raj", "Vivek", "Manish","Shyam", "Dinesh", "Rahul", "Mukesh", "Naveen" };
        ArrayAdapter<String> adp=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,android.R.id.text1,name);
       listView.setAdapter(adp);
        listView.setOnItemClickListener(onClick);
    }
    OnItemClickListener onClick=new OnItemClickListener() {

                        @Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,n  long id) {
                        Toast.makeText(getApplicationContext(),name[position], Toast.LENGTH_LONG)
                                                            .show();
                                   
                        }
};

ListActivity

The ListActivity class which extends the Activity class was designed to simplify the handling of ListViews.

Default Layout

ListActivity has a default layout that consists of a single, full-screen list in the center of the screen. Therefore you are not required to use the setContentView() to assign a layout in your Activity’s  onCreate() method.
It defines the onListItemClick() method for handling selection of list items. Internally the ListActivity registers an OnItemClickListener on the ListView.
ListActivity allows to set the adapter to the ListView via the setListAdapter() method.
Same above example using ListActivity( not needs of main.xml file for layout )
SimpleListActivity.java

package org.nk;


import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

public class SimpleListActivity extends ListActivity {
             String[] name;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       // not  provide layout
      //setContentView();

        name = new String[] { "Raj", "Vivek", "Manish","Shyam", "Dinesh", "Rahul", "Mukesh", "Naveen" };
        ArrayAdapter<String> adp=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,android.R.id.text1,name);
       setListAdapter(adp);
       
    }
            @Override
            protected void onListItemClick(ListView l, View v, int position, long id) {
                        Toast.makeText(getApplicationContext(),name[position], Toast.LENGTH_LONG)
                        .show();
            }
           
}

Customize the screen layout

However, if you desire, you can customize the screen layout by setting your own view layout with setContentView() in onCreate(). To do this, your own view MUST contain a ListView object with the id "@android:id/list"
In the same above example now create a layout file


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
   
    <ListView android:id="@android:id/list"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
               android:background="#aa0000"
               android:layout_weight="1"
               android:drawSelectorOnTop="false"/>

</LinearLayout>
Now, modify above activity code to provide mylayout
package org.nk;

import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;

public class MyListActivity extends ListActivity {

               public void onCreate(Bundle icicle) {
                               super.onCreate(icicle);
// now provide layout
setContentView(R.layout.mylayout);

String[] name = new String[] { "Raj", "Vivek", "Manish","Shyam", "Dinesh", "Rahul", "Mukesh", "Naveen" };
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                                                             android.R.layout.simple_list_item_1,name);
setListAdapter(adapter);

               }
}

You can define own layout for the row

newlayout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >
 
        <TextView
        android:id="@+id/mytext"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="hello text"
        android:textSize="18px" >
    </TextView>
 
</LinearLayout>

Now, change default row layout and provides newlayout and ID of the View to which the data is written is mytext

package org.nk;

import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;

public class MyListActivity extends ListActivity {

               public void onCreate(Bundle icicle) {
                               super.onCreate(icicle);
// no more this
// setContentView();

String[] name = new String[] { "Raj", "Vivek", "Manish","Shyam", "Dinesh", "Rahul", "Mukesh", "Naveen" };
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                                                             R.layout.newlayout,R.id.mytext, name);
setListAdapter(adapter);

               }
}

An ArrayAdapte is backed by an array of arbitrary objects. By default this class expects that the provided resource id references a single TextView. If you want provided resource id references more than one TextView, custom adapter can be used.

Custom Adapter


main.xml

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

    <TextView
        android:id="@+id/name"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"       
        android:text="@string/hello" />
    <TextView
        android:id="@+id/edu"
        android:layout_width="fill_parent"       
        android:layout_height="wrap_content"
        android:text="@string/hello" />
    <TextView
        android:id="@+id/sex"
        android:layout_width="fill_parent"       
        android:layout_height="wrap_content"
        android:text="@string/hello" />
     <TextView
        android:id="@+id/sep"
        android:layout_width="fill_parent"
        android:layout_height="2dp"
        android:background="#00aa00"
        android:text=" " />

</LinearLayout>

Create a Adapter class by sub classing ArrayAdapter and override getView() method

MyListAdapter

package org.nk;
import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class MyListAdapter extends ArrayAdapter<User>{
            private final Context context;
            private final List<User> objects;
            public MyListAdapter(Context context,List<User> objects) {
                        super(context,R.layout.main, objects);
                        this.context=context;
                        this.objects=objects;
                       
            }

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                        LayoutInflater inflater = (LayoutInflater) context
                                                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                        //           Inflate a new view hierarchy from the specified xml resource
                                    View rowView = inflater.inflate(R.layout.main, parent, false);
                                    TextView nameView = (TextView) rowView.findViewById(R.id.name);
                                    TextView eduView = (TextView) rowView.findViewById(R.id.edu);
                                    TextView sexView = (TextView) rowView.findViewById(R.id.sex);
                                    User u=objects.get(position);
                                    nameView.setText("Name : "+u.getName());
                                    eduView.setText("Edu : "+u.getEdu());
                                    sexView.setText("Sex : "+u.getSex());
                        return rowView;
            }
}
package org.nk;
public class User {
String name;
String edu;
String sex;
public User(String name, String edu) {
            super();
            this.name = name;
            this.edu = edu;
}

public User(String name, String edu, String sex) {
            super();
            this.name = name;
            this.edu = edu;
            this.sex = sex;
}

public String getSex() {
            return sex;
}

public void setSex(String sex) {
            this.sex = sex;
}

public String getName() {
            return name;
}
public void setName(String name) {
            this.name = name;
}
public String getEdu() {
            return edu;
}
public void setEdu(String edu) {
            this.edu = edu;
}

}

MyListActivity.java
package org.nk;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
import android.widget.Toast;
public class MyListActivity extends ListActivity {
    List<User> ulist;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ulist=new ArrayList<User>();
        ulist.add(new User("Raj","MCA","Male"));
        ulist.add(new User("Rani","MBA","Female"));
        ulist.add(new User("Ranjeet","BCA","Male"));
        ulist.add(new User("Puja","BBA","Male"));
        ulist.add(new User("Sima","BBA","Female"));      
        setListAdapter(new MyListAdapter(this, ulist));
    }
    protected void onListItemClick(ListView l, View v, int position, long id) {              
                        //get selected items
                        User user = (User) getListAdapter().getItem(position);
                        Toast.makeText(this, user.getName(), Toast.LENGTH_SHORT).show();

            }
}


No comments:

Post a Comment