SimpleCursorAdapters and ListViews
Hey everyone,
So this post will be a comprehensive tutorial on using SimpleCursorAdapters, as well as creating your own Custom CursorAdapters, and also using the alternative BaseAdapters / Custom BaseAdapters, and finally how these different CursorAdapters are used to create listviews in your activities! This post will be replete with examples, so hopefully you guys find it helpful.
So first off, what is a SimpleCursorAdapter and how do you use it? So let’s say you want to create a list that “mimics” the native contact list. In order to do this, you’re going to need two XML files in addition to your ListActivity – so I’ll define all three here:
public class ListA extends ListActivity { @Override public void onCreate(Bundle savedInstance) { setContentView(R.layout.list_example); // some code Cursor cursor = getContentResolver().query(People.CONTENT_URI, new String[] {People._ID, People.NAME, People.NUMBER}, null, null, null); startManagingCursor(cursor); // the desired columns to be bound String[] columns = new String[] { People.NAME, People.NUMBER }; // the XML defined views which the data will be bound to int[] to = new int[] { R.id.name_entry, R.id.number_entry }; // create the adapter using the cursor pointing to the desired data as well as the layout information SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this, R.layout.list_example_entry, cursor, columns, to); // set this adapter as your ListActivity's adapter this.setListAdapter(mAdapter); } }
And now this is how we would define:
R.layout.list_example
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content" > <ListView android:id="@android:id/android:list" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
Note a few things here. This is just the very basic layout your Activity can take… for instance if you wanted to pad the list with TextViews or EditTexts above and or below then that’s perfectly fine – you would just need to add them in the appropriate place relative to the defined ListView. Also, note that the id of the ListView is “@android:id/android:list”, CONTRARY to what many sources say (some say it is “@id/android:list” or “@+id/android:list” but this will throw you an error). Now, with our Activity’s layout defined, the last thing we need to do is define each entry’s layout, and so I typically create a separate XML file and make it something like:
R.layout.list_example_entry
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/name_entry" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="28dip" /> <TextView android:id="@+id/number_entry" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="28dip" /> </LinearLayout>
Now, with this list entry each row of our list will look like:
Contact Name
Contact Number
And so you can use this R.layout.list_example_entry file to customize how you want EACH ROW ENTRY to look like.
Now it’s important to look at these three pieces of code and see the relationship between each one. In your SimpleCursorAdapter, first you obtain a cursor pointing to the table of data that you want. In your CursorAdapter, it will move the cursor down each row and first obtain the desired information, and then it will add that information to the correct places in your list_example_entry. How does your CursorAdapter know which columns from your data table to retrieve? Well that’s precisely what the
String[] columns = new String[] { People.NAME, People.NUMBER };
line in our example does, and once this data is retrieved where does it know which views in our XML layout to place them in? Well that’s what the “to” array is for:
int[] to = new int[] { R.id.name_entry, R.id.number_entry };
And finally, where does the cursor know which layout file to look for R.id.name_entry and R.id.number_entry? Well you supply it in the constructor of the SimpleCursorAdapter:
// note the 2nd parameter tells the cursor which row entry layout to use SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this, R.layout.list_example_entry, cursor, columns, to);
And so that’s how everything is pieced together!
The next post will be on creating your own Custom CursorAdapters.
– jwei
Very useful, thank you !
It’s very good!!
I want to add a onListItemClickListener.
but that is not running.
I think, a problem is TextView’s focusable.
Where can I add a code to setFocusable ?
please give me a e-mail.
ysjh8501@nate.com
thank you. Have a good day.
If you want to handle also checkboxes, and handlers to know which checkbox was checked, stuff like that which was very trivial with ArrayAdapters, how you can do it with CursorAdapter ?
Thank,
Just what I wanted, thanks for the post.
easy and clear explanation .. Thanks..
Cursor cursor = getContentResolver().query(People.CONTENT_URI, new String[] {People._ID, People.NAME, People.NUMBER}, null, null, null);
startManagingCursor(cursor);
For this part right, if I want to use my database and own data, in what way should I put it?
Database Name: 789
Table: Entry
So you would replace the “People.CONTENT_URI” with your table/databases’s URI (URI is basically just like a pathname to the database), and then instead of People._ID, People.NAME, etc, you would just include your own table columns.
– jwei
oh ok! i will try, thanks alot!
i have to create the database URI in the database class right?
DBAdapter.CONTENT_URI – that is what i changed it to, however it still force closes my application! Please help, thank you.
I created my own content provider and i want to use this code to show the listview. however, nothing has came out. please help me out! :>
Hello,
you might want to mention that you need to add
android.permission.READ_CONTACTS
to your applications permissions, otherwise it will crash.
For people with this problem:
Double click AndroidManifest.xml, click “Add … “, then “Uses permissions” and then
android.permission.READ_CONTACTS if you are using Eclipse.
Great i too had the same error..thanks for your help
Thankyou for your sample.What will be your AndroidManifest.xml code? I tried running the program but my program is closing abruptly.Please guide me as I feel there is some problem with the manifest.xml file.
No, mine did not crash, ive added the permissions already! :> but i still cant show!
I added the permissions as well,when I tried to debug the code i find everything going on good until the last statement.I dont know why am i ending up in an error “application stopped unexpectedly”.I put whole of my code in a try catch block as well,Its not even throughing any exception.
What does the error in the log cat say?
– jwei
Hi,
thanks for this tutorial,
just a quick comment, I needed to add
super.onCreate(savedInstance);
just after: public void onCreate(Bundle savedInstance) {
to stop my app from crashing.
Hi, Thanks for this nice example,
Instead of retrieving profile picture (ImageView) I have just put the CheckBox view and want to implement a Contacts list with
Name, Number and a CheckBox with the each list Item to select multiple contacts number and display them on another activity. But i am not getting the whole idea.
I am beginner to android please could you tell me how to do this??
android:id=”@android:id/android:empty”
I had been scratching my head on this one for weeks… Thanks, man!
This article was very helpful for me. Thank you very much.
thanks from a new Android developer… this helped me understand SimpleCursorAdapters and get unstuck. Thanks!
Thanks for explaining that. I had a hard time figuring out what a SimpleCursorAdapter is used for.
can i make a multi_select list using simple cursor adapter
thanks for the tutorial!
there’s just one thing missing… the attribute the data is assigned to.
i checked the the class doc of SimpleCursorAdapter, and it explains the procedure right at the beginning.
so, to assign to different view attributes than text or image, just use SimpleCursorAdapter.setViewBinder().
the setViewValue() method in your ViewBinder can then do whatever it likes with the data. nice!
Its really nice tutorial.Very helpful.
Thanks for the tutorial, it’s very useful; I have a question about the visualisation of the table’s data, I want to know if it’s possible to display the column names (Contact Name and Contact Number) above the data itself. Thanks in advance, regards.
Hey Maximiliano,
Hm not quite sure what you’re asking – are you simply asking to retrieve the column name from the cursor? Or are you asking about how you would actually visualize a table’s data on the front end of the application (i.e. using a TableView or something like that)
– jwei
Hello jwei512, thanks for reply my message, my question was related to the visualisation of the table’s data but I finally could handle it. What I wanted to do is to show at the top of the table the column’s names (for example “id” and “date”), but with the SimpleCursorAdapter I couldn’t found a way to include an extra row which contains that information, so I made a little trick with the layout in which the SimpleCursorAdapter is inflated (not the layout passed as a parameter), creating a couple of TextView which are at the top of the layout and also are invisible, and when I’m going to set the listAdapter with the SimpleCursorAdapter I just make those TextView visible. I hope I haven’t been confusing in my wording, my English is not the best. Thanks again for the reply, cheers.
really, you’ve made my interest in programming grow a Mile longer, thanks. Tutorials on android are complicated, and the simple ones are spoon feeds. The problem is after completing a tutorial on android, what you can do is change the tittle and few strings to make your own. But your presentation makes it possible to create my very own codes. Thanks.
Thanks. Your post is so useful.
Thanks, this is a very clear and useful explanation.
Thanks for this tutorial. I want to dress this with my app. Can you tell me how i can fill ListView pulling data from remote database?
I use POST method with HttpClient.
Thanks man.
Andre
Hey Andre,
I’ll get to that in one of my new posts for my Google App Engine series.
– jwei
Very very understandable and useful. Thank You!
You have no idea how much I appreciate this post! I have been struggeling with SimpleCursorAdapter for almost a week and this totally showed me where I was failing! You got it, it was: “@android:id/android:list”
Good Post,thanks~
Thanks, very helpful!
thank you!!!!!! congratulations!!!
it help me very much!!
Im diego, Im from argentina!!
see youu
thanx for ur code this code is usefull to me too much……….
I used this simplecursoradapter. It’s fine for some projects. But, I got the problem of bad performance when I used it with more than one thousands of records. Any ideas to solve this.
I set onListItemCLick event for each item in the list.
And i need a toggle button in each list item showing the satus of the item,How can i do that please help….
Please Help..
nice share, thank’s
Nice share. Thanks! Still useful although it is almost two years old.
Very nice explained !
Love you man.. Just started developing my first app.. None of the website gave such brief exp.. Thanks a lot..!!!!!
Hi I have two buttons instead of the text boxes in your list_example_entry.xml.
I need to handle events for them. Please help me in this regard. Thank you in advance.
Nice one. Very simple to understand. Thanks to giving this.
Howdy! I just wish to offer you a huge thumbs up for the great information you’ve got right here on this post. I’ll be coming back to your site for more soon.
Great article,now i had made some changes in my listview i.e. i added textbox in listview in which user may enter his opinion. now the problem is I can’t figure out how to update back this listview data to the database with user opinions.
How do you translate this using LoaderManager ? startManagingCursor() is deprecated. What do you pass in the constructor of SimpleCursorAdapter as cursor parameter ?
Great ! ! ! I was struggeling around with this stuff … you made my day !!!
very useful, thnks man!
Thank you very much. It helped me a lot to grasp the “How it works”. Thanks again.
really nice article to understand cursoradapter..good job..
You need to take part in a contest for one of the greatest sites
on the web. I most certainly will recommend this blog!
Thanks Rob – means a lot =)
– jwei
very usefull
Thanks. I was confused about the existence of row entry xml and the “to” layout xml. Now, its clear. Thank you.
I’m semi-surprised that @android:id/android:list works for you.. the second android: is not necessary, you only need to prefix the category; @android:id/list works fine.<
Also, for those looking for a very simple list (just text items for example), you can comment out setContentView() and use android.R.layout.simple_list_item_1 or android.R.layout.simple_list_item_2 for your list item layout; then the list item ids you use are e.g. android.R.id.text1…
If i have name and phone number in database so how i can show a custom list view from the database.
Hey Anurag,
I have a handful of tutorials regarding custom list adapters – please see CursorAdapter Tutorials.
Hope you find that helpful.
– jwei
It is very helpful.
Thanks
Shafiq
Thank you, but how can I delete an item from the ListView using this code, upon a longclick on the item in the ListView?
Hi Joe,
So step 1) there are two ways to define a long click. The first is through the onLongClickListener() (see http://stackoverflow.com/questions/4402740/android-long-click-on-a-button-perform-actions) and the second is through a context menu (see http://developer.android.com/guide/topics/ui/menus.html. Which one you use just depends on the functionality you want (one automatically does an action the other brings up a menu with options for the user to choose).
Step 2) is then deleting an item from the list. This is simple – just delete it from your underlying ArrayList or database and call the ListView’s notifyDataSetChanged() method.
Hope this helps.
– jwei
would you please give some tips how to use simpleCursorAdapter without ListActivity?
Hi Vahid,
Could you specify in what ways you wish to use the SimpleCursorAdapter? Typically they are used in conjunction with ListActivities so I’d need to know what usage you’re looking for to help.
– jwei
Useful tutorial. Thank you!
If you want to handle also checkboxes, and handlers to know which checkbox was checked, in list view and to know which check box are checked….
Hey.. I’m new to Android Developing.
Can you tell how to dynamically “ADD” more items to the list?
Hi Abhishek,
What do you mean by dynamically add more items? Is your CursorAdapter pointing to a database or content provider? If so there is a notifyDataChanged() method – this will allow your list to update as more things are added to the database.
– jwei
As of Android 4.03 the code
SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this, R.layout.list_example_entry, cursor, columns, to);
Will not work. It needs to be
SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this, R.layout.list_example_entry, cursor, columns, to, 0);
I have no idea what the last zero does but without it nothing is ever put in the list and with it it works properly.
Also the this.setListAdapter(adapter) appears to fail but using setListAdapter (adapter) works.
Are you sure? The old constructor *has* to work, otherwise a bunch of apps would quite simply break. Perhaps you mean it is deprecated?
The 0 is for the flags parameter — FLAG_AUTO_REQUERY and FLAG_REGISTER_CONTENT_OBSERVER as per the documentation. From what I understand the old/deprecated constructor specifies those two automatically, which is discouraged due to the queries happening in the main thread.
There’s also no reason for this.setListAdapter(adapter) to fail but setListAdapter(adapter) to work as they’re actually identical. Did you make any code changes after that one perhaps?
Yep, very sure. No other changes made at all, with the ,0 it works without nothing ever gets displayed. I couldn’t believe it either, which is why it took so long to find.