Android custom ListView tutorial (including source code)

This tutorial will show how to prepare ListView with custom items and buttons (with click handlers) like this:

Android ListView with custom items

Source Code

The source code for this tutorial is in this post. You can download it and use as You like.

1. Create single list item layout

Item consists of three views: name, value (EtitTexts) and delete (Button). Its atom_pay_list_item.xml layout is as follows:

<?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="horizontal" >

    <EditText
        android:id="@+id/atomPay_name"
        android:layout_width="0sp"
        android:layout_height="fill_parent"
        android:layout_weight="2"
        android:gravity="center_vertical"
        android:hint="@string/EnterPays_atomPay_nameHint"
        android:textAppearance="?android:attr/textAppearanceSmall" />

    <EditText
        android:id="@+id/atomPay_value"
        android:layout_width="0sp"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:gravity="center"
        android:inputType="numberDecimal"
        android:text="@string/EnterPays_TextView_ZeroValue"
        android:textAppearance="?android:attr/textAppearanceSmall" />

    <ImageButton
        android:id="@+id/atomPay_removePay"
        android:layout_width="@dimen/width_button"
        android:layout_height="fill_parent"
        android:contentDescription="@string/emptyText"
        android:onClick="removeAtomPayOnClickHandler"
        android:src="@android:drawable/ic_menu_delete" />
</LinearLayout>

Notice, that the button has onClick handler defined in xml layout file. This is because I want to refer its action to specific list item, so handler will be implemented in Activity file and each button will know to which list item it belongs. Later I will show how to do it in detail.

2. Create list item adapter

This is java class that is a controller for atom_pay_list_item.xml. It keeps references for all of its views and puts these references in tags and extends ArrayAdapter. My adapter looks as follows:

public class AtomPayListAdapter extends ArrayAdapter<AtomPayment> {

	private List<AtomPayment> items;
	private int layoutResourceId;
	private Context context;

	public AtomPayListAdapter(Context context, int layoutResourceId, List<AtomPayment> items) {
		super(context, layoutResourceId, items);
		this.layoutResourceId = layoutResourceId;
		this.context = context;
		this.items = items;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		View row = convertView;
		AtomPaymentHolder holder = null;

		LayoutInflater inflater = ((Activity) context).getLayoutInflater();
		row = inflater.inflate(layoutResourceId, parent, false);

		holder = new AtomPaymentHolder();
		holder.atomPayment = items.get(position);
		holder.removePaymentButton = (ImageButton)row.findViewById(R.id.atomPay_removePay);
		holder.removePaymentButton.setTag(holder.atomPayment);

		holder.name = (TextView)row.findViewById(R.id.atomPay_name);
		holder.value = (TextView)row.findViewById(R.id.atomPay_value);

		row.setTag(holder);

		setupItem(holder);
		return row;
	}

	private void setupItem(AtomPaymentHolder holder) {
		holder.name.setText(holder.atomPayment.getName());
		holder.value.setText(String.valueOf(holder.atomPayment.getValue()));
	}

	public static class AtomPaymentHolder {
		AtomPayment atomPayment;
		TextView name;
		TextView value;
		ImageButton removePaymentButton;
	}
}

Here I display list of AtomPayment class items. There are three most important elements here:

  • AtomPayListAdapter constructor: sets some private fields and calls superclass constructor. It also gets the List of AtomPayment objects. Its implementation is obligatory.
  • AtomPaymentHolder: static class that holds references to all views that I have to set in this list item. I also keep the AtomPayment object that references to this particular item in list. I set it as tag for ImageButton, that will help me to find the AtomPayment item on list, that user wanted to remove
  • Overriden getView method: called by superclass. Its goal is to return the single List row. I create its fields and setup their values and store them in static holder. Holder then is put in row’s tag element. Note that there is an performance issue: row is being recreated each time it is displayed. I used to add some flag in holder like isCreated, and set it to true after row was already created. then you can add if statement and read tag’s holder instead of creating it from scratch.

My AtomPayment.java is quite simple as for now and it looks a bit like BasicNameValuePair:

public class AtomPayment implements Serializable {
	private String name = "";
	private double value = 0;

	public AtomPayment(String name, double value) {
		this.setName(name);
		this.setValue(value);
	}
...
}

Of course there are additionally getters and setters for each private field.

3. add ListView in your activity layout xml file

In the simpliest form, it is enough to add this view to activity layout:

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

4. Set up adapter to this list view in Activity Java code

In order to display items in ListView you need to set up its adapter and map it to some other ArrayList of AtomPayment objects (as I am extending an Array adapter here). Here is code that is responsible for binding adapter to editPersonData.getAtomPayments() ArrayList:

AtomPayListAdapter adapter = new AtomPayListAdapter(AddNewPerson.this, R.layout.atom_pay_list_item, editPersonData.getAtomPayments());
ListView atomPaysListView = (ListView)findViewById(R.id.EnterPays_atomPaysList);
atomPaysListView.setAdapter(adapter);

5. Adding / removing items to ListView (and its adapter)

Adapter is handled just like any other ArrayList, so adding new element to it is as simple as:

AtomPayment testAtomPayment = new AtomPayment("Test", 13);
adapter.add(testAtomPayment);
adapter.remove(testAtomPayment);

6. Handle Remove Payment button click event

In an activity’s code, where ListView is displayed, add public method that will handle remove button click action. The method name has to be exactly the same as it was in atom_pay_list_item.xml:

android:onClick="removeAtomPayOnClickHandler"

The method body is as follows:

public void removeAtomPayOnClickHandler(View v) {
	AtomPayment itemToRemove = (AtomPayment)v.getTag();
	adapter.remove(itemToRemove);
}

The AtomPayment object was stored in ImageButton’s Tag element. Now it is enough to read it from Tag, and remove this item from the adapter.

7. Incorporate remove confirmation dialog window

Probably you need also make sure that user intentionally pressed the remove button by asking him additional question in confirmation dialog like this one:

Confirmation dialog sample

Please go to my post that contains tutorial how to show and handle confirmation dialog to find out how to do it.

Source Code

The source code for this tutorial is in this post. You can download it and use as You like.

Did I help you?
I manage this blog and share my knowledge for free sacrificing my time. If you appreciate it and find this information helpful, please consider making a donation in order to keep this page alive and improve quality

Donate Button with Credit Cards

Thank You!

65 thoughts on “Android custom ListView tutorial (including source code)

  1. Hi,

    congratulations very good tutorial.

    Could you add such a confirmation dialog for deletion? It should be simple, but I can not find how to do it.

    Thanks again for the tutorial.

    regards

    1. Instead of edittext may i know how to change the edittext to a spinner inside your open source coding?

    1. You mean custom ListView or remove confirmation dialog source code? Both instructions are pretty well described, so it should be easy to develop it by yourself.

      My source code is currently a part of big project, so it would be hard for me to post it.

    1. Not really because this is a part of bigger project, so there is big overhead in project.

      I suppose that this is described precisely enough. But let me know if you still can’t handle it and realy need source code.

  2. Hey the line “adapter.remove(itemToRemove)” Throws —> java.Lang.IllegalStateException caused by java.Lang.UnsupportedOperationException
    ?????? Please help!

  3. Actually I have loaded a List(using arrayAdapter) with data from Database… Now I want to delete a row… But when I use your above code it Force closes
    :(

  4. As in this example, you can implement the functions onSaveInstanceState and onRestoreInstanceState?

      1. I apologize for the stupid question. I want to know about the function onSaveInstanceState and onRestoreInstanceState

    1. My code wasn’t tested with it – This is meant to be simple tutorial on listView, not on saving and restoring states.

      Usually you restore your state in onCreate(). onRestoreInstanceState() is called after onStart()
      You can use the put methods to store values in onSaveInstanceState():
      protected void onSaveInstanceState(Bundle icicle) {
      super.onSaveInstanceState(icicle);
      icicle.putLong(“param”, value);
      }

  5. Can you please merge the codes in their own respective classes and xml? I’m having a hard time to understand, Thanks!

    1. OK – I’ll write source code for it and share it.

      Unfortunately I won’t be able to do it until next saturday (27.4.2013)… Please stay tuned!

  6. hello, your tutorial is really good and simple so understan for a newbie like myself :D. But i have an issue, i made buttons like you did in the row of the listview theses buttons have to activate a checkbox each, and it’s work but i can’t save the states of thoses checkbox so i can’t be sure if every row has their own checkboxes when i click on the buttons .

  7. Add OnCheckedChanged listener for checkbox in adapter and in that listener you will have to persist checkbox state in your model (atomPayment item in my case)

    See my sorce code, how I persist editText’s value

  8. hello again,

    the listview you made, how can you save the listview when i.e i hit the back button and then come back again on the activity, all the items i create dissapeared .

    1. You need to implement some data storage for it and persist all the list items (ArrayList) in it. For example you can use shared preferences. And after that, when you create activity, you have to load this data back

      Search for post regarding shared preferences tutorial on my blog

  9. hello!

    very nice tutorial!:) i like it.
    but i have 1 problem: your second edittext is numberDecimal. i changed it, but still appers as “0.0”.
    well my problem is: i need it to be only “1”, and just to be hint, so if i click, user can enter a value without erasing the “1” value.

    i can’t figure it out, so pls help :)
    thanks in advance

    1. probably the default value is set to “0.0”. please check it in list item’s xml file. change it to 1.

      As far as I remember – the default value (0.0) is taken from strings.xml. check there

      1. “0.0” is not found in your entire soure.
        i changed it to an int value (to be round only) on the insert method

        public void onClick(View v) {
        int k=1;
        adapter.insert(new AtomPayment(“1”, k), 0);

        also don’t works

        thanks for fast reply

    2. Change type ‘double’ to ‘int’ in AtomPayment.java for ‘value’ field. Should help :)

      1. hellyeah! had to change some method parameters too, but it’s working:)
        BIGBIGTHANKYOU

  10. i’m struggling with a TextView wich sums up the added listitems’ Edittext values.
    how should i doit?
    can’t figure it out :(
    any tips or ideas?

    1. In shared preferences. Search for another post on my blog how to do it.

      If not shared preferences, you can use database our file storage

      1. Actually i mean,
        if we put the value in edittext for all the edittext present in the listview
        and press submit button ,then i want to send all the value of edittext value to the server for further process….
        so i am unable to get the value entered in the edittext.

  11. Hey i have added my customlistview in database.
    you are right. when i click on that button my view is deleted but not from database. so what to do to delete that as well as from database.

  12. Very helpful for me..really great..but how to read the exact values of edit text from this list?? Please help me.

    1. each row / item in an adapter has holder in its tag. Choose item in adapter you want to read, get this holder from this item, find edittext in holder and read its content

  13. Im having problems with the row.settag() and in the method which is fired on the OnClick … v.Gettag() ) is always null.

    you place the holder object into the row.setTag();

    then you cast the v.gettag() as a AtomPayment. how does it do that when it holds other information i.e. editviews and image button??

  14. say if for every row in the listview i just did row.settag(count++); each row would have a unique number… on the onclick method how would i get that from the View?

    1. by gettag, parsed to the class that you put there. but remember, that you set tag to the whole view, so you need to listen to the view click.

      I am not sure whther it is possible to hold pribmitives in tag, while setTag expects object. Maybe it uses autoboxing.

      Fire my source code and analyze how does it happen that in my case the object is valid, while your tag is null

  15. Nice tutorial, I was really struggling on how the connection was made from the button in the listview item and using it’s handler in the main event. Thanks for the help.

  16. Nice tutorial! I’d like to sum the numbers inside the EditTexts, but I have no idea how to find out. Any ideas? Thank you so much!

  17. Thanks for this post.
    I’m really new in Android and Java programming and with your example I was trying to make a simple thing but I could not get there.
    I just wanted to let the user press the add button if the 1st row has any vaue.

    Could you tell me how to do it?

  18. Hello, congratulations for the tutorial!
    I have a question though, how do we listen for changes in the EditText fields? And how to retrieve them?
    Thank you in advance!

  19. Very good Tutorial, I love it.
    I still have a problem accessing the object in the ListView.

    public void ListView_Selected(View v){
    depot.temporary = ((paper)v.getTag());
    startActivity(new Intent(getApplicationContext(), DetailView.class));
    }

    i want to copy the selected object in a temporary object so I can work and display that temporary object.

    but the View returns an empty object

  20. editPersonData.getAtomPayments()

    What should I do about this? I totally dont get it. Please Help.

  21. Hi,

    Your Tutorial is awesome, i am new to this listview topic and got really complicated functionality to implement.
    i am having some questions regarding this tutorial:

    1. how can i get a particular index of listitem if i press delete button.
    2. how can i add the 2nd edittext values and get its sum on a textview.

    please explain about this…

    and my other doubt is inside this link:
    please help me out with this one.

    https://stackoverflow.com/questions/47728322/recognitionlistener-gives-nullpointerexception-with-viewholder

Give Your feedback: