I am new to android. I want to show inserted data from database to a table. I have used List to get the data.
public List<user> getAllUsers() {
List<user> users = new ArrayList<user>();
Cursor cursor = database.query(SqlLiteHelper.TABLE_USER, allColumns, null, null, null, null, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
user varUser = cursorToUser(cursor);
//Log.v("user name",varUser.getName().toString());
users.add(varUser);
cursor.moveToNext();
}
//Log.v("user name",users.get(0).getName().toString());
cursor.close();
return users;
}
private user cursorToUser(Cursor cursor) {
user varUser = new user();
//Log.v("user id", cursor.getString(1).toString());
varUser.setID(cursor.getLong(0));
varUser.setName(cursor.getString(1));
varUser.setPhone(cursor.getString(2));
varUser.setEmail(cursor.getString(3));
return varUser;
}
I wrote this code on UserDataSource.java
Then where i need to show those data i use the following codes
databaseSource = new UserDataSource(this);
databaseSource.open();
List<user> values = databaseSource.getAllUsers();
Log.v("information", values.get(0).getName().toString());
ArrayAdapter<user> adapter = new ArrayAdapter<user>(this, android.R.layout.simple_list_item_1, values);
setListAdapter(adapter);
This is not adding the values in the list. I use the log.v to check whether the data is coming back or not. And i found that the data is coming perfectly from the database. Only when i try to print the List or insert it to the simple_list_item_1 then it is doing the problem.
It is printing
com.example.given_n_take.user#41221338
Buts its suppose to print the name from the database.
Database table name is user.
Please let me know what am i missing.
here is my xml file of layout where i am trying to add those list
<?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" >
<Button
android:id="#+id/all_user_back"
style="?android:attr/buttonStyleSmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text="Back" />
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="384dp" >
</ListView>
</LinearLayout>
If your list shows com.example.given_n_take.user#41221338 this means that you are missing a toString method in your user class. Implement a toString that returns the name of the user.
It's because your ArrayAdapter calls the toString() method of your user object. You either have to implement to toString() method or if you want to show more than a string in your list, you have to write your own Adapter.
you are getting wrong result because
Log.v("information", values.get(0).getName().toString());
values.get(0) will return class User consist of values like name ,id, phone no etc and to acces name you are calling getName method which is perfect. But for adapter you are passing List<user> values directly. So when adapter extract data out of it it will extract class User out of it not the different values. SO to access values you have to get the positioned value of list, extract values name, id etc and then pass it to adapter
Related
I am quite new to Android development. I managed to get data saved to SQLite database. Now, what I want is to view these data when I call viewData(). I have viewData() which shows data as a Toast as I made it as a sample. Now I need these data to show on a new activity using a ListView, but the number of data to show is depending on how many data is in the database at the moment, If user saved 10 items then I want all the 10 items to shown up. How can I do it?
I hope my question is clear.
Thanks in advance.
you could use ListView
declare it in your layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ListView
android:id="#+id/list"
android:layout_height="wrap_content"
android:layout_width="match_parent">
</ListView>
</LinearLayout>
in yor activity declare a globar var:
ListView listView;
and onCreate
listView = (ListView) findViewById(R.id.list);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1, values);
// Assign adapter to ListView
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id){
// ListView Clicked item index
int itemPosition = position;
// ListView Clicked item value
String itemValue = (String) listView.getItemAtPosition(position);
}
});
datos can be an array that you can populate with data that you extract from your data base and that's the most simple way to show it. if you want to customizise your listView you can create a custom adapter, or in other way the newest element that replace listView is ReciclerView. I hope tihs help you
You can use a SimpleCursorAdapter:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ListView answerList=(ListView)findViewById(R.id.answerList);
Cursor mCursor = getData();
startManagingCursor(mCursor);
// now create a new list adapter bound to the cursor.
// SimpleListAdapter is designed for binding to a Cursor.
ListAdapter adapter = new SimpleCursorAdapter(this, // Context.
android.R.layout.two_line_list_item,
mCursor, // Pass in the cursor to bind to.
// Array of cursor columns to bind to.
new String[] {"_id", "answer"};
// Parallel array of which template objects to bind to those
// columns.
new int[] { android.R.id.text1,android.R.id.text2 });
// Bind to our new adapter.
answerList.setAdapter(adapter);
}
private Cursor getData() {
String sq = "Select _id, answer from foo";
Cursor c = db.rawQuery(sql);
return c;
}
I will try to give an in-depth answer to this.
Whenever you want to fetch and display a list of data from the database, you can use a ListView, GridView, Spinner, etc for it.
You can use a CursorAdapter which can make the job of querying and displaying data much more simple and easy.
Here is a basic visual representation of it,
Step 1
Firstly, you need to create a database. As mentioned in your question, it is clear that you know how to create a database and put some data into it. So I am not going into the depths of it.
Step 2
We need to define the layout to be used for the individual items in the ListView and save it as res/layout/item_todo.xml This is just a sample layout, you can design any kind of layout you want to.
<?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" >
<TextView
android:id="#+id/tvBody"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Study cursors"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/tvPriority"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="3"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
Step 3
Now we need to define an adapter. Here we are using a CursorAdapter which converts a Cursor (that you provide) into Views (defined by your layout).
There are two methods, newView and bindView which we need to override. The newView is responsible for inflating newViews for the first time and the bindView is responsible for binding the data to the Views.
public class TodoCursorAdapter extends CursorAdapter {
public TodoCursorAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
}
// The newView method is used to inflate a new view and return it,
// you don't bind any data to the view at this point.
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.item_todo, parent, false);
}
// The bindView method is used to bind all data to a given view
// such as setting the text on a TextView.
#Override
public void bindView(View view, Context context, Cursor cursor) {
// Find fields to populate in inflated template
TextView tvBody = (TextView) view.findViewById(R.id.tvBody);
TextView tvPriority = (TextView) view.findViewById(R.id.tvPriority);
// Extract properties from cursor
String body = cursor.getString(cursor.getColumnIndexOrThrow("body"));
int priority = cursor.getInt(cursor.getColumnIndexOrThrow("priority"));
// Populate fields with extracted properties
tvBody.setText(body);
tvPriority.setText(String.valueOf(priority));
}
}
Step 4
Now as you can clearly see, that the constructor needs a Context and a Cursor. Now we need to query the database and retrieve the data into a Cursor and pass it to the adapter.
// TodoDatabaseHandler is a SQLiteOpenHelper class connecting to SQLite
TodoDatabaseHandler handler = new TodoDatabaseHandler(this);
// Get access to the underlying writeable database
SQLiteDatabase db = handler.getWritableDatabase();
// Query for items from the database and get a cursor back
Cursor todoCursor = db.rawQuery("SELECT * FROM todo_items", null);
Step 5
This is the last step where we need to instantiate the adapter and attach the ListView with the adapter to populate the data.
// Find ListView to populate
ListView lvItems = (ListView) findViewById(R.id.lvItems);
// Setup cursor adapter using cursor from last step
TodoCursorAdapter todoAdapter = new TodoCursorAdapter(this, todoCursor);
// Attach cursor adapter to the ListView
lvItems.setAdapter(todoAdapter);
Android 2.3.3
I have a table in database with two columns. I wish to retrieve this data and show them in a ListView having two textviews(first column in first textview and second column in second textview) and repeat this till for all the rows in the database. I have read a few examples on(custom adapter and listview) how to do, but the more I read, the more I get confused.
Can someone give me a head start on how to do this? I can use a dynamic listview, but I wish to do it using the static one.
Here is the Layout of the row in the listview:
<?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"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingBottom="5dp"
android:paddingTop="5dp" >
<TextView
android:id="#+id/txtView_History_Expression"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="0.50"
android:text="Expression"
android:textColor="#FFFFFF"
/>
<TextView
android:id="#+id/txtView_History_Result"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="0.50"
android:text="Result"
android:textColor="#316DA2" />
</LinearLayout>
Here is the XML with ListView:
<?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" >
<TextView
android:id="#+id/txtView_History_Header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="HISTORY"
android:gravity="center"
android:textSize="24dp"
android:textColor="#316DA2"
android:paddingTop="10dp"
/>
<ListView
android:id="#+id/lvHistory"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
I am retrieving the data from database and storing it in a Cursor. I want to read data from Cursor and give those values to the textviews in the listview.
I have a table in database with two columns. I wish to retrieve this
data and show them in a ListView having two textviews(first column in
first textview and second column in second textview) and repeat this
till for all the rows in the database. I have read a few examples
on(custom adapter and listview) how to do, but the more I read, the
more I get confused.
Hello. This algorithm is not too tricky. You need to these steps:
Create some method for getting rows from db. You can return either
List<TableDataType> or directly Cursor.
Create subclass of some ListAdapter to get better control over it.
Set ListAdapter to ListView.
Example:
Method for getting data from db:
public List<DataType> getAll() {
List<DataType> objects = new ArrayList<DataType>();
DataType child = null;
Cursor c = null;
try {
String query = "select * from TableName";
c = db.rawQuery(query, null);
if (c.moveToFirst()) {
child = new DataType();
child.setId(c.getInt(c.getColumnIndex("id")));
child.setName(c.getString(c.getColumnIndex("name")));
objects.add(child);
}
return objects;
}
finally {
if (c != null) {
c.close();
}
if (db != null) {
db.close();
}
}
}
Then you can create own Adapter extending from BaseAdapter and set data to TextViews in getView() method and create RowHolder that will be arbitrary Object that holds childs(widgets) of each row
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
// inflate convertView and add row to RowHolder
// set RowHolder as tag of row .. convertView.setTag(rowHolder);
}
else {
// just recycle views so get existing RowHolder
rowHolder = (RowHolder) convertView.getTag();
}
// set data to widget(s)
rowHolder.getFirstTextView().setText(dataSource.get(position).getId());
...
}
RowHolder can looks like
public class RowHolder {
private View row;
private TextView idColumn;
public RowHolder(View v) {
this.row = v;
}
public TextView getIdColumn() {
if (idColumn == null) {
idColumn = (TextView) row.findViewById(R.id.idColumnId);
}
return idColumn;
}
}
And finally set Adapter to ListView and work is done.
Note:
DataType is own defined Object. It presents Table in your db where properties of Object are identical with columns in Table.
There is other approach and return from db Cursor and a usage of SimpleCursorAdapter or CursorAdapter. Here are nice examples:
Android Listview Example using CursorAdapter and SQLite
database
SimpleCursorAdapters and
ListViews
you should follow this flow
step 1 -> get data from data base and Fill the List with getter Setter
Step 2 -> Create BaseAdapter Class and give that list in this class[Here you need to see BaseAdpter bind methods]
Stap 3 -> Bind BaseAdapter object with Your ListView
All you can do is take a look at Bind the List view from Database with Cursor Adapter.
Also check the ListView Example using Cursor Adapter with SQLiteDatabase.
I hope this will guide you.
Thanks.
I was looking for an alternative to a spinner, since the first item is always selected (which causes me issues), and I found some examples for using an AlertDialog with a list instead.
I am having two problems:
The list is displaying and is formatted ok, but there are no values in it. I know the query is returning, and the cursor/adapter has the data in it.
This may be a symptom of #1 - but when I select a blank row, the Cursor cursor2 = (Cursor) ((AdapterView) dialog).getItemAtPosition(which); statement causes a crash (it's a ClassCastException).
I had similar code previously which set the adapter to a spinner object, and the data was displaying fine.
I don't think the adapter is getting set correctly, and I have been unable to come up with a solution thus far.
Any thoughts?
Thanks!
btnDenomination.setOnClickListener(new View.OnClickListener()
{
public void onClick(View w)
{
Cursor cursor = coinDB.myDataBase.rawQuery("select _id, denomination_desc from denomination", null); // must select the _id field, but no need to use it
startManagingCursor(cursor); // required in order to use the cursor in
String[] from = new String[] {"denomination_desc" }; // This is the database column name I want to display in the spinner
int[] to = new int[] { R.id.tvDBViewRow }; // This is the TextView object in the spinner
cursor.moveToFirst();
SimpleCursorAdapter adapterDenomination = new SimpleCursorAdapter(CoinsScreen.this,
android.R.layout.simple_spinner_item, cursor, from, to );
adapterDenomination.setDropDownViewResource(R.layout.db_view_row);
new AlertDialog.Builder(CoinsScreen.this)
.setTitle("Select Denomination")
.setAdapter(adapterDenomination, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
Cursor cursor2 = (Cursor) ((AdapterView<?>) dialog).getItemAtPosition(which);
strDenomination_id = cursor2.getString(0); // Gets column 1 in a zero based index, the first column is the PKID. this could
// be avoided by using a select AS statement.
Log.d("Item Selected", strDenomination_id );
TextView txtDenomination = (TextView) findViewById(R.id.textDenomination);
txtDenomination.setText(cursor2.getString(1));
dialog.dismiss();
}
}).create().show();
}
});
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="#+id/LinearLayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView android:text=""
android:id="#+id/tvDBViewRow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FF0000" />
</LinearLayout>
Are you sure R.id.tvDBViewRow is the id of the TextView in the layout android.R.layout.simple_spinner_item ? From this, the TextView's id should be android.R.id.text1.
So new answer for the second issue :)
I think you should reuse the initial cursor instead of trying to get a new one... Can you try to do :
adapterDenomination.moveToPosition(which);
strDenomination_id = adapterDenomination.getString(0);
in the onClick() ?
I'm try to write a little application and the releated unit tests.
I have a ListView binded to a SimpleCursorAdapter reading data from an SQL table.
The Activity#onCreate() method is:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dbHelper = new DatabaseHelper(this);
SQLiteDatabase dbRead = dbHelper.getReadableDatabase();
String[] columns={BaseColumns._ID, ENTRY_VALUE};
cursor = dbRead.query(ENTRIES_TABLENAME, columns, null, null, null, null, null);
String[] from = {"value"};
int[] to = {R.id.value};
adapter = new SimpleCursorAdapter(this, R.layout.list_entry, cursor, from, to);
setListAdapter(adapter);
}
My test inside the unit-test is:
#UiThreadTest
public void testTheElementInsideTheDBisDisplayedInTheList() {
String entryValue = "clipboard entry 1";
DatabaseHelper dbHelper = new DatabaseHelper(cmActivity);
Cursor beforeCursor = selectAllEntries(dbHelper);
// The table, at the begining of the test, is empty, I control that
assertEquals(0, beforeCursor.getCount());
// I insert the new value in the table
insertEntry(dbHelper, entryValue);
// and I control that is really inside the table now
Cursor afterCursor = selectAllEntries(dbHelper);
assertEquals(1, afterCursor.getCount());
// This method calls the method "requery()" on the cursor associate
// to the listView's adapter to update the list view
cmActivity.updateList();
// I control that the listView is updated
assertEquals(1, entryList.getCount());
// Now I try to retrive the only child inside the list view
// to extract the text inside it and to compare this text with
// the value inserted into the DB table.
TextView entryView = (TextView) entryList.getChildAt(0);
String viewText = entryView.getText().toString();
assertEquals(entryValue, viewText);
}
My problem is in the third-last row:
TextView entryView = (TextView) entryList.getChildAt(0);
I sude getChildAt() to get the first TextView child of the ListView. But this method returns null, so the test gets a NullPointerException.
Maybe getChildAt() is not the right method to get the View child from a ListView, so which is the correct one?
I see from the documenation that the method works with GroupView, I didn't use them, do I need to configure a default GroupView and put all the entry inside it? In this way, will getChildAt(0) work? Is this the correct way to setup a ListView?
thank you, bye
Andrea
As asked by Vivek, I post here the main.xml:
<?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="fill_parent">
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView android:id="#android:id/empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Empty set"
/>
</LinearLayout>
As you can see is very very basic. Also le list entry is very simple:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/value"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp" >
</TextView>
I doubt if the list is populated when you call getChildAt() method. So call getChildCount() method and see if the list is populated. And post back the output here.
Edit:
Now I understand the problem. ListView.getCount() method returns the number of items populated in the list. And ListView.getChildCount() Method or ListView.getChildAt() Method will return 0 here because these methods will return a value only when the view is visible to the user. You can use getChildAt() method only after the textviews are generated. i.e If you use the method in OnItemClick method of the listview, or any listview listener implementation, you will get the desired output. What is the need to get the reference to the textviews here in this method anyways?
I'm working on my first Android app and can't figure out how to get my SimpleCursorAdpater to populate the view. The cursor that I'm passing in has results in it, so the problem must be somewhere in instantiating the adapter or in binding it to the view. I'm sort of at my wits end since no exceptions are thrown and I can't really step
into setListAdapter.
Here is how i get my cursor in the first place:
Searches searches = new Searches(this);
SQLiteDatabase db = searches.getReadableDatabase();
//select _id, Name, Search FROM Searches;
Cursor c = db.query(
SearchConstants.TABLE_NAME,
FROM, null, null, null,
null, null);
startManagingCursor(c);
And this is the schema do my db:
CREATE TABLE Searches (_id INTEGER PRIMARY KEY, Name Text, Search TEXT)
Here are the two lines where things start to fall apart:
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.search, cursor, FROM, TO);
setListAdapter(adapter);
My main layout looks like this:
<ListView
android:id="#android:id/android:list"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#android:id/android:empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/empty" />
Here is the view to fill with each result:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10sp">
<TextView
android:id="#+id/_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/colon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=": "
android:layout_toRightOf="#id/name" />
<TextView
android:id="#+id/search"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:textStyle="italic"
android:layout_toRightOf="#id/colon" />
</RelativeLayout>
Finally here are the static variables I used:
//search query stuff
private static String[] FROM = {SearchConstants._ID, SearchConstants.NAME_COLUMN, SearchConstants.SEARCH_COLUMN};
//where to paste search results
private static int[] TO = {R.id._id, R.id.name, R.id.search};
/**
* Table name
*/
public static final String TABLE_NAME = "Searches";
/**
* Name Column
*/
public static final String NAME_COLUMN = "Name";
/**
* Search Column
*/
public static final String SEARCH_COLUMN = "Search";
I think this is all of the relevant code. I have no idea how to proceed at this point, so any suggestions at all would be helpful.
Thanks,
brian
PS: Looks like theres a lot of great suggestions here - i'm not ignoring them i just havent had the chance yet. Thanks for the advice! At some point i'll go thru them all and try to give some feedback as to which things worked well for me.
You can step into the code if you have the source code. Luckily, Android is open source. To easily attach source code in Eclipse, see:
http://android.opensourceror.org/2010/01/18/android-source/
As for the problem itself, you said in a comment above that you iterate all of the items before creating the adapter. If you are not creating a new cursor after iteration, you probably need to rewind it or the adapter might think it's empty.
cursor.moveToFirst()
Please don't worry about any internal binding aspects. I'm sure there is an easy way out. Try the following:
First, just to ensure your cursor really has got data where it's needed, put the line
System.out.println("cursor.getCount()="+cursor.getCount());
right before the call of setAdapter(). But surely, you already tested to get a row count ;-) So the following might be more interesting.
To check if your binding fails, please test with:
android:id="#+id/android:list"
instead of :
android:id="#android:id/android:list"
in your main.xml. Same thing with: android:id="#+id/android:empty".
And if you still don't get results, you can also try using a list default xml-layout (like simple_list_item_1) for displaying, which would look like this:
ListAdapter adapter = new SimpleCursorAdapter(this,
// Use a template that displays a text view
android.R.layout.simple_list_item_1,
// Give the cursor to the list adapter
cursor,
// Map the NAME column in your database to...
new String[] {SearchConstants.NAME_COLUMN} ,
// ...the "text1" view defined in the R.layout.simple_list_item_1
new int[] {android.R.id.text1}
);
Just copy paste it into your activity and see what happens.
Hope you're done with that!
Just got the same problem and found how to allow the Simplecursoradapter creation to not fail.
In your cursor, the query of the database MUST contain the table primary key even if you don't need it ! If not it will fail and crash...
Hope it will help others with the same problem !
Alright, I noticed you used a column name with a capital letter. Make sure you use the exact identifier in the DB scheme (the sqlite column names are case sensitive). But in the code you provided the column identifiers match.
So, if the cursor you use really has got the data, try out the above code at first (instead of some custom layout) for creating a SimpleCursorAdapter and it should work. Here's another little example for the activity code (as I don't know yours):
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.dbManager = new DatabaseManager(this);
setContentView(R.layout.main);
registerForContextMenu(getListView()); // catch clicks
if (!showList()) {
TextView tv = new TextView(this);
tv.setText(getString(R.string.txt_list_empty));
setContentView(tv);
}
}
private boolean showList() {
final Cursor c = dbManager.fetchListData();
startManagingCursor(c); // when the Activity finishes, the cursor is closed
if (!c.moveToFirst())
return false;
final SimpleCursorAdapter myAdapter = new SimpleCursorAdapter(
this, android.R.layout.simple_list_item_2, c,
new String[]{"name"} , new int[]{android.R.id.text1} );
setListAdapter(myAdapter);
return true;
}
Before spending a lot of time where you encounter problems, rather start where things are still working and take small steps for extensions. If you keep them simple, there's no great magic in using adapters.
You might try inserting a ViewBinder for debugging. You can use it to inspect which values are being passed for which views in the SimpleCursorAdaptor. Or just use it to manually do the binding yourself.
Something like this should work:
adapter.setViewBinder(new SimpleCursorBinder());
and then
public class SimpleCursorBinder implements SimpleCursorAdpater.ViewBinder {
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
/* set breakpoints and examine incoming data. */
// returning false, causes SimpleCursorAdapter to handing the binding
boolean bound = false;
String columnName = cursor.getColumnName(columnIndex);
TextView bindingView = null;
int viewId = view.getId();
// could just use this opportunity to manually bind
if (columnName.equals(SearchConstants._ID)) {
bindingView = (TextView)(viewId == R.id._id ? view : null);
} else if (columnName.equals(SearchConstants.NAME_COLUMN)) {
bindingView = (TextView)(viewId == R.id.name ? view : null);
} else if (columnName.equals(SearchConstants.SEARCH_COLUMN)) {
bindingView = (TextView)(viewId == R.id.search ? view : null);
}
if (bindingView != null) {
bindingView.setText(cursor.getString(columnIndex));
bound = true;
}
return bound;
}
}
It doesn't look like you've done anything wrong, You haven't shown all your code though so it might be difficult to spot any errors.
Not sure if the line startManagingCursor(c) does this for you but in my examples i have the following lines after my query has completed. Given your example looks absolutely fine it could be your cursor needs resetting to the first item.
(Ah, just noticed kichik pointed this out , but i'll leave my example.)
if (c != null) {
c.moveToFirst();
}
My queries often look like:
public Cursor getQueryCursor()
{
Cursor c;
c = null;
try{
c = myDataBase.query(TABLE_MYTABLE, new String[] {
COLUMN_ID,COLUMN_LABEL, COLUMN_TEXT},
null,
null,
null,
null,
null);
if (c != null) {
c.moveToFirst();
}
}catch(Exception ec)
{
Log.w("MY_APP", ec.getMessage());
}
return c;
}
Then when applying your query result i also often put try/catch statements around it and add break points at these points (sometimes the getMessage() returns null but other properties of the exception will highlight the issue. I also check the out put from LogCat. I've often been able to work out the root of my problems with the following.
try{
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.search, cursor, FROM, TO);
setListAdapter(adapter);
}catch(IllegalStateException e)
{
Log.w("MyApp", e.getMessage());
}catch(Exception es)
{
Log.w("MyApp", es.getMessage());
}
Please check your SQLite database, it must have a column '_id' as a primary key.
I had same kind of problem, and finally figure it out with this...