this code is working fine - i'm loading a bunch of rows into the SimpleCursorAdapter and the ListView displays them. nice.
SimpleCursorAdapter adapter;
Cursor cursor;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView lv = (ListView)findViewById(R.id.main_lv_projects);
lv.setOnItemClickListener(this);
String[] columns = new String[] { CompassDataProvider.ORG_NAME };
int[] names = new int[] { R.id.organisation_row_name};
cursor = this.managedQuery(CompassDataProvider.CONTENT_URI_ORGANISATIONS, null, null, null, null);
adapter = new SimpleCursorAdapter(this, R.layout.organisation_row, cursor, columns, names);
lv.setAdapter(adapter);
startManagingCursor(cursor);
}
But when i'm inserting a new row via
long rowID = db.getWritableDatabase().insert(CompassDBHelper.ORGS_TABLE_NAME, "", values);
getContext().getContentResolver().notifyChange(CONTENT_URI_ORGANISATIONS, null);
return Uri.withAppendedPath(CONTENT_URI_ORGANISATIONS, ""+rowID);
the list view is not updateing itself - i thought the SimpleCursorAdapter is notified an can then reload its view - not?
the new row is created - i checked on this
when i'm using
cursor.requery();
adapter.notifyDataSetChanged();
in my UI threat the new data gets loaded correctly... whats the observer/listener pattern here that i did not get? :)
thanks,
Martin
The cursor is being passed into the SimpleCursorAdapter by value and not reference. So, calling cursor.requery has no effect. To get this to work the way you want, you're really going to need to implement a listAdapter and process your cursor in there.
Related
How can I delete a list item and get an updated list using onContextItemSelected?
How can I delete a row using context menu?
Code:
case R.id.Delete_Note:
Database_Notepad db=new Database_Notepad(Create_Task.this);
db.DeleteNote();
break;
My Database:
public void DeleteNote(int rowId) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(Table_Notepad, Col_ID + " = ?", new String[] { String.valueOf(rowId) });
db.close();
}
How can I update my listview after the deletion of an item?
This is how I'm setting data to listview:
Database_Notepad db = new Database_Notepad(Create_Task.this); Cursor c = db.Get_All_Note();
String[] from = new String[] {Database_Notepad.Col_File_Name,Database_Notepad.Col_Due_Date};
int[] to = new int[] {R.id.titlename, R.id.duedatetext};
SimpleCursorAdapter madapter = new SimpleCursorAdapter(Create_Task.this, R.layout.file_row, c, from, to);
this.setListAdapter(madapter);
getListView().setOnItemClickListener(this);
registerForContextMenu(getListView());
db.close();
As per your comment you success to delete the row item, but you failed to update your listview,
So whenever some changes made in listview data you should notify your adater by applying notifyDataSetChanged() like this adapter.notifyDataSetChanged() ,it will reflect in your listview if some items get added or deleted.
hope it works!
I have a Database with a table called users(_id,name).
I am using the following method to get all the records in the ascending order of names
public Cursor getAllNames() {
return db.query(DATABASE_TABLE, new String[] { KEY_ROWID, KEY_NAME },
null, null, null, KEY_NAME+" ASC", null);
}
Now i am retrieving the Cursor in the List Activity as follows
DBAdapter db= new DBAdapter(this);
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.lview);
ListView l=(ListView) findViewById(R.id.listView1);
db.open();
Cursor c=db.getAllNames();
db.close();
}
I am trying to use Simple Cursor Adapter to iterate thru the names and assign it to the List View. But since it has be depreciated how to achieve the same ?
SimpleCursorAdapter hasn't been deprecated, one of it's constructors has. If you want to attach Cursor data to a ListView then I strongly suggest the SimpleCursorAdapter option since it's the most easy way to do it. I believe the new SimpleCursorAdapter is offered in the v4 support library.
You can create a custom Adapter that extends BaseAdapter and holds an ArrayList of items.
After you call the getAllNames() and you have all your items in the Cursor, iterate over the Cursor and put all those items in the ArrayList from the CustomAdapter. Then just set the CustomAdapter as the ListView adapter.
My cursor is fetch data from sqlite.
msgsdbadapter = new MSGSDBAdapter(this);
msgsdbadapter.open();
cons_cursor = msgsdbadapter.fetchConversations();
startManagingCursor(cons_cursor);
After that I create a SimpleCursorAdapter and assign it to ListView. The ListView now can display some records well.
String[] from = new String[] { MSGSDBAdapter.KEY_FROM, MSGSDBAdapter.KEY_MSG, MSGSDBAdapter.KEY_DATE};
int[] to = new int[] { R.id.lblFrom, R.id.lblMsgExcerpt, R.id.lblDate };
cons_cursor_adapter = new SimpleCursorAdapter(context, R.layout.conversation_item, cons_cursor, from, to);
lvConversations.setAdapter(cons_cursor_adapter);
Next, I insert new row into table and notify dataset changed, but the ListView is not update
msgsdbadapter.createMsg(msg);
cons_cursor_adapter.notifyDataSetChanged();
And when I should close the db connection?
You need to either requery() the existing Cursor, or run the query again to get a fresh Cursor and swap the new Cursor into your CursorAdapter.
The best solution if your using the ListFragment is to put this in inside this sample:
public SimpleCursorAdapter myNote;
public class NOteLIST_MAIN extends ListFragment {
#SuppressWarnings("deprecation")
#Override
public void onResume() {
super.onResume();
myNote.getCursor().requery();//Don't forget to put these on onResume }
private void DataLoader(){private void DataFiller(){
myNote = new SimpleCursorAdapter(getActivity(), R.layout.notes_row_line, notesCursor, from, to,0);
setListAdapter(myNote);}
}
ListView is populating with the items from the Cursor wich I pass in the SimpleCursorAdapter, but each time I open the application these items are re-added to the listview increasing it continously. When I use SimpleAdapter, i do something like this:
static final ArrayList<HashMap<String, String>> foobar = new
ArrayList<HashMap<String,String>>();
SimpleAdapter adapter = new SimpleAdapter(this, foobar, R.layout.list_item, String[] from, int[] to);
setListAdapter(adapter);
Doing next, solve my problem:
#Override
public void onDestroy(){
super.onDestroy();
foobar.removeAll(foobar);
}
But now, I don't want to delete the database content,so how to solve it if I have a SimpleCursorAdapter? like this one:
> SimpleCursorAdapter myadapter = new SimpleCursorAdapter(this, R.layout.list_item, cursor, String[] from, int[] to);
I have tried setListAdapter(null) or cursor.close(),and many others, but no efect...
Now, these hapen when I exit the application using "back" button of the device. If I press "home" button, when I came back I have the same number of items.So the list is duplicating every time I exit with "back" button.
Solved thanks to Kaediil's answer.The commented lines is what I have improved. The hole class:
public class DataBaseActivity extends ListActivity {
DataBaseMethods dbmet; //is the class that handle database and auxiliar methods working on it
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list);
dbmet = new DataBaseMethods(this);
Cursor mycursor= dbmet.getItems(); // 1. add new cursor
try{
if(!mycursor.moveToFirst()){ //2.check if there are items in the database
dbmet.addItems("Daniel","Son","Karate-kid");
dbmet.addItems("Silv", "Stalone", "Terminator");
dbmet.addItems("foo", "bar", "buz");
} //
showDatabaseContent();
}
finally{
dbmet.close();
}
}
public void showDatabaseContent(){
DataBaseMethods dbmet = new DataBaseMethods(this);
try{
Cursor cursor = dbmet.getItems();
SimpleCursorAdapter myadapter = new SimpleCursorAdapter(this, R.layout.item_list, cursor, dbmet.FROM, TO);
setListAdapter(myadapter);
}
finally{
dbmet.close();
}
}
Umm, this line is suspect:
If does it matter, I'm populating the database in this activity's onCreate(), but I have tried to populate it also from other activity and I get the same behaviour for the listview.
In the populating of the database call do you check to see if the database is already populated?
It sounds like you just keep adding more copies to the DB that the cursor is pointing to.
public void showDatabaseContent(){
DataBaseMethods dbmet = new DataBaseMethods(this);
try{
Cursor cursor = dbmet.getItems();
SimpleCursorAdapter myadapter = new SimpleCursorAdapter(this, R.layout.item_list, cursor, dbmet.FROM, TO);
setListAdapter(myadapter);
-->> myadapter.notifyDataSetChanged(); <<----
}
finally{
dbmet.close();
}
}
You need to call notifyDataSetChanged() to signal the list to invalidate itself ONLY with the new data.
NOTE:
If the issue is from the Database class. Make sure you are not reinserting items in the database every time you start the application. I might mixed your problem, wither the items are duplicate in the listview or in the database. I'm deeply sure that you are reinserting the data every time you run the app.
I am trying to manage a simple list in an Android application. The contents of the list are maintained in a SQLite database. When the user selects and holds on a specific row, a context menu appears with a "Delete" option. When they select "Delete", the row is deleted from the database, but the view does not refresh. When I back out of the application and get back in, the appropriate row has been removed. So, I know the row is deleted, it's just the ListView that doesn't refresh.
Here are the relevant bits of code...
In the onCreate method...
SQLiteDatabase db = tasks.getReadableDatabase();
Cursor cursor = db.query(TABLE_NAME,
new String[] { _ID, TITLE, DETAILS, },
null, null, null, null, TITLE + " DESC");
startManagingCursor(cursor);
ListView lv = (ListView) findViewById(R.id.list);
lv.setAdapter(new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1,
cursor,
new String[] {TITLE},
new int[] { android.R.id.text1}
));
In the onContextItemSelected method...
switch(item.getItemId()) {
case 0:
SQLiteDatabase db = tasks.getWritableDatabase();
ListView lv = (ListView) findViewById(R.id.list);
SimpleCursorAdapter adapter = (SimpleCursorAdapter) lv.getAdapter();
db.delete(TABLE_NAME, "_ID=?", new String[] {adapter.getCursor().getString(0)});
adapter.notifyDataSetChanged(); // Not working, clears screen and doesn't reload
return true;
}
return super.onContextItemSelected(item);
What am I missing?
Thanks!
Get rid of the notifyDataSetChanged() and call requery() on your Cursor. Here is a sample project demonstrating this.