Search code examples
androidandroid-listviewandroid-cursoradapter

Updating ListView using SimpleCursorAdapter ( without re-initializing adapter )


I have a ListView widget in an Activity that I would like to update using a SimpleCursorAdapter. I am able to add items to my ListView by initializing a SimpleAdapter every time upon the push of a Button, like so:

public void saveButton(View view){

    EditText editText = (EditText) findViewById(R.id.edit_text);
    String data = editText.getText().toString();

    database.insertData(data);
    Log.v("database",database.getAllData().toString());

    // initialization happens every time upon click. 
    // This method is coupled to a Button's onClick attribute.   

    SimpleCursorAdapter adapter = new SimpleCursorAdapter(getApplicationContext(),R.layout.layout_file,database.getAllData(),new String[]{"candy"},new int[]{R.id.label},SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
    listview.setAdapter(adapter);

}

However, I would like to replicate the same behaviour without having to re-initialize SimpleCursorAdapter every time. I tried using the bindView method, but my ListView does not update itself.

Here's the entire code. First for the Activity:

public class MainActivity extends Activity {

ListView listview; 
DatabaseTools database; 

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    database = new DatabaseTools(getApplicationContext(),null,null,1);

    //ArrayList<String> result = database.getAllData();
    Cursor cursor = database.getAllData();

    listview = (ListView) findViewById(R.id.list_view);
    SimpleCursorAdapter adapter = new SimpleCursorAdapter(getApplicationContext(),R.layout.layout_file,cursor,new String[]{"candy"},new int[]{R.id.label},SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
    listview.setAdapter(adapter);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

public void saveButton(View view){

    EditText editText = (EditText) findViewById(R.id.edit_text);
    String data = editText.getText().toString();

    database.insertData(data);
    Log.v("database",database.getAllData().toString());

    SimpleCursorAdapter adapter = new SimpleCursorAdapter(getApplicationContext(),R.layout.layout_file,database.getAllData(),new String[]{"candy"},new int[]{R.id.label},SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
    listview.setAdapter(adapter);

}

}

And the SQLiteOpenHelper class:

public class DatabaseTools extends SQLiteOpenHelper {

private final String mDatabaseName = "CandyStore";


public DatabaseTools(Context context, String name, CursorFactory factory,
        int version) {
    super(context, name, factory, version);
    // TODO Auto-generated constructor stub
}

@Override
public void onCreate(SQLiteDatabase db) {

    String query = "CREATE TABLE "+ mDatabaseName + " (_id INTEGER PRIMARY KEY AUTOINCREMENT, candy TEXT)";

    db.execSQL(query);

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // TODO Auto-generated method stub

}

public void insertData(String data){

    SQLiteDatabase database = this.getWritableDatabase();

    ContentValues values = new ContentValues();

    values.put("candy", data);


    database.insert(mDatabaseName, null, values);

}

public Cursor getAllData(){

    ArrayList<String> datalist = new ArrayList<String>();

    String query = "SELECT * FROM " + mDatabaseName;

    SQLiteDatabase database = this.getReadableDatabase();

    Cursor cursor = database.rawQuery(query, null);

    if(cursor != null){
        cursor.moveToFirst();
    }

    return cursor;
}

}

Solution

  • Answering own question. The solution to this issue is obtained by calling the changeCursor() method of SimpleCursorAdapter.

    public void saveButton(View view){
    
        EditText editText = (EditText) findViewById(R.id.edit_text);
        String data = editText.getText().toString();
    
        database.insertData(data);
        Log.v("database",database.getAllData().toString());
    
        // using the changeCursor method provides a cursor that can be
        // updated with a 'screenshot' of the latest data returned by the database.     
        SimpleCursorAdapter adapter = (SimpleCursorAdapter) listview.getAdapter();
        adapter.changeCursor(database.getAllData());
    
    }
    

    According to the documentation, changeCursor()

    changes the underlying cursor to a new cursor. If there is an existing cursor it will be closed.