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);}
}
Related
I had UI-problem when I test my app on an android 2.3 device , the Content of Drop down suggest list for AutoCompleteTextView does not show
But when I test my app on an android 4.2 device , the Content of Drop down suggest list
works
I'am using android Support Library. and I'am using Theme.AppCompat.Light Theme for Application.
loadData method which i used to fill the Content of Drop down suggest list
private void loadData () {
final int[] to = new int[]{android.R.id.text1};
final String[] from = new String[]{"keyword"};
SimpleCursorAdapter adapter = new SimpleCursorAdapter(MainActivity.this, android.R.layout.simple_dropdown_item_1line, null, from, to,SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
adapter.setCursorToStringConverter(new SimpleCursorAdapter.CursorToStringConverter() {
#Override
public CharSequence convertToString(Cursor cursor) {
final int colIndex = cursor.getColumnIndexOrThrow("keyword");
return cursor.getString(colIndex);
}
});
adapter.setFilterQueryProvider(new FilterQueryProvider() {
#Override
public Cursor runQuery(CharSequence keyword) {
Cursor results= keywordSearch.searchKeywords(keyword.toString());
return results;
}
});
tbxSearch.setThreshold(2);
tbxSearch.setAdapter(adapter);
}
I had solve the UI-Problem by changing layout of drop down list.
Change:
SimpleCursorAdapter adapter = new SimpleCursorAdapter(MainActivity.this, android.R.layout.simple_dropdown_item_1line, null, from, to,SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
To:
SimpleCursorAdapter adapter = new SimpleCursorAdapter(MainActivity.this, R.layout.support_simple_spinner_dropdown_item , null, from, to,SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
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!
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.
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.
I'm trying to refresh a ListView that uses a ListAdapter created as a SimpleCursorAdapter.
Here is my code for creating the Cursor and ListAdapter in onCreate which populates the ListView.
tCursor = db.getAllEntries();
ListAdapter adapter=new SimpleCursorAdapter(this,
R.layout.row, tCursor,
new String[] columns,
new int[] {R.id.rowid, R.id.date});
setListAdapter(adapter);
Then, I add some data to the db in another method, but I can't figure out how to refresh the ListView. Similar questions on stackoverflow and other places mention using notifyDataSetChanged() and requery(), but neither are methods of ListAdapter or SimpleCursorAdapter.
I'm able to get the ListView to refresh by creating a new adapter and calling setListAdapter again.
I named it adapter2 in the other method.
tCursor = db.updateQuery();
ListAdapter adapter2=new SimpleCursorAdapter(this,
R.layout.row, tCursor,
columns,
new int[] {R.id.rowid, R.id.date});
setListAdapter(adapter2);
I'm not sure why this is necessary, but it works for now. If anyone has a better solution, I'm willing to try it.
The method notifyDataSetChanged comes from the SimpleCursorAdapter parent class BaseAdapter. The parent implements ListAdapter and you should be able to pass it to your ListView.
Try:
tCursor = db.getAllEntries();
BaseAdapter adapter=new SimpleCursorAdapter(this,
R.layout.row, tCursor,
new String[] columns,
new int[] {R.id.rowid, R.id.date});
setListAdapter(adapter);
Then you should be able to use notifyDataSetChanged.
In that case I recommend to go with custom Adapter, by extending the BaseAdapter class.
You can define the adapter as a class variable if it needs to be accessed from other methods in the same class. Then you can call changeCursor() to refresh the ListView.
public class mainActivity extends AppCompatActivity {
// Define the Cursor variable here so it can be accessed from the entire class.
private SimpleCursorAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_coordinator_layout)
// Get the initial cursor
Cursor tCursor = db.getAllEntries();
// Setup the SimpleCursorAdapter.
adapter = new SimpleCursorAdapter(this,
R.layout.row,
tCursor,
new String[] { "column1", "column2" },
new int[] { R.id.rowid, R.id.date },
CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
// Populate the ListAdapter.
setListAdapter(adapter);
}
protected void updateListView() {
// Get an updated cursor with any changes to the database.
Cursor updatedCursor = db.getAllEntries();
// Update the ListAdapter.
adapter.changeCursor(updatedCursor);
}
}
If the list view needs to be updated from methods in another class, the adapter variable should be declared public static instead
public static SimpleCursorAdapter adapter;