1

I'm working with a database and I'm trying to populate a ListView with each row of my table. I've successfully created and queried data, but I can't get anything to appear in the ListView using a SimpleCursorAdapter.

public class History extends ListActivity {
SQLiteDatabase db;
DbHelper DbHelper;
ListView lv;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.history);
    DbHelper = new DbHelper(this);
    db = DbHelper.getWritableDatabase();
    lv = getListView();

    final String[] from = { DbHelper.TYPE, DbHelper.TITLE, DbHelper.CONTENT };
    final String[] column = { DbHelper.C_ID, DbHelper.TYPE, DbHelper.TITLE,
            DbHelper.CONTENT };

    final int[] to = { R.id.list_row_title, R.id.list_row_content };
    Cursor cursor = db.query(DbHelper.TABLE_NAME, column, null, null, null,
            null, null);
    SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
            R.layout.history_list_row, cursor, from, to);

    lv.setAdapter(adapter);

    /*
     * Display as Toast for development purposes
     */
    // move to first row
    cursor.moveToFirst();
    // move to the next item each time
    while (cursor.moveToNext()) {
        // get string and column index from cursor
        String name = cursor
                .getString(cursor.getColumnIndex(DbHelper.TYPE));
        String title = cursor.getString(cursor
                .getColumnIndex(DbHelper.TITLE));
        String content = cursor.getString(cursor
                .getColumnIndex(DbHelper.CONTENT));

        Toast.makeText(this,
                "Title: " + title + "\n" + "Content: " + content,
                Toast.LENGTH_SHORT).show();
    }
    cursor.close();
}

}

This is my custom ListView row to display 3 Strings from the database

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >

<TextView
    android:id="@+id/list_row_title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Title"
    android:textAppearance="?android:attr/textAppearanceLarge" />

<TextView
    android:id="@+id/list_row_content"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Content"
    android:textAppearance="?android:attr/textAppearanceMedium" />

<TextView
    android:id="@+id/list_row_type"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Type"
    android:textAppearance="?android:attr/textAppearanceSmall" />

The Toast messages appear perfectly, but nothing appears in the ListView.

ericcarboni
  • 88
  • 1
  • 13
  • 3
    I don't think you should mess with, much less close the cursor outside of the adapter as it messes up the cursor position and the loading of the data. A closed cursor will be no good inside your adapter. – ebarrenechea Feb 22 '13 at 00:45
  • You can pass `null` to [`changeCursor(Cursor)`](http://developer.android.com/reference/android/widget/CursorAdapter.html#changeCursor(android.database.Cursor)) if you don't need it anymore. If you use [`LoaderCallbacks`](http://developer.android.com/reference/android/app/LoaderManager.LoaderCallbacks.html), you can call it in [`onLoaderReset()`](http://developer.android.com/reference/android/app/LoaderManager.LoaderCallbacks.html#onLoaderReset(android.content.Loader)). Otherwise, don't close the cursor outside of the adapter. The adapter manages the cursor itself. –  Feb 22 '13 at 01:05

2 Answers2

2

I'm noticing a couple of issues here.

First,

final int[] to = { R.id.list_row_title, R.id.list_row_content };

should be

final int[] to = { R.id.list_row_type, R.id.list_row_title, R.id.list_row_content };

Secondly, you are setting the adapter incorrectly. Instead of getting the list view and setting the adapter, you can set the adapter directly:

SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
        R.layout.history_list_row, cursor, from, to);
setListAdapter(adapter);

Third, you are closing the cursor after the loop.

//Closes the Cursor, releasing all of its resources and making it completely invalid.
cursor.close();

So by the time the list view is displaying items, the cursor no longer has the rows associated with it

Aaron
  • 46
  • 3
  • Thanks for the help, this fixed my problem! I have a question though. I was following a tutorial that said to call close() on the cursor or it wouldn't work. Taking that line out fixed my problem so my question is, when is it appropriate to close the cursor? – ericcarboni Feb 24 '13 at 16:35
  • ericcarboni - I have posted just such a question. It appears that there is no standard answer for this - 'when is it appropriate to close the cursor' in this case? – JJJones_3860 Dec 22 '19 at 03:24
0

You will need to set the TextView's text in the while loop.

 TextView tv1=(TextView)findViewById(R.id.list_row_content);
 tv1.setText(content);
razzy
  • 198
  • 1
  • 10