I'm sorry to ask about what seems to be a simple problem but I've been looking for a solution for hours and now I can't stand it anymore.
My app is very simple. I've got "tasks" in a SQLite db, and I populate a listView with this db like this :
_dataAdapter = new TaskAdapter(_c, _taskDAO.getTasks());
_listTask.setAdapter(_dataAdapter);
which returns an arrayList of Task.
Problem is, when I click the dialog to remove a task, it removes it from the db but it's still on the screen, that's why I need to refresh the listView.
case DialogInterface.BUTTON_NEUTRAL:
_taskDAO.removeTask(1);
_dataAdapter.notifyDataSetChanged();
break;
But it does not work. I think it's due to the fact that I remove the task from the db but not from the adapter but I'm not quite sure.
Anyway, if someone's got a solution ...
If your adapter is an ArrayAdapter or BaseAdapter, the data source of your ListView is not the DB itself but the List you provide to the adapter.
You must update the datasource of your adapter (give him a new list) then call
_dataAdapter.notifyDataSetChanged();
Another solution would be to recreate the adapter :
_dataAdapter = null;
_dataAdapter = new TaskAdapter(_c, _taskDAO.getTasks());
_listTask.setAdapter(_dataAdapter);
Hope it helps
try,
(listName.getAdapter()).notifyDataSetChanged();
Related
I want to populate RecyclerView using database. As currently there is no inbuilt adapter for populating RecyclerView using database, I have used CursorRecyclerAdapter by Shywim. I have created a sample App to test it and it worked fine. The feature I didn't liked is having an _id column in the resultset and calling swapCursor() on each database operation, mostly insert and delete. This goes same with ListView when using SimpleCursorAdapter. My query is what if I use ArrayList as the dataset instead of directly using the Cursor.
Benefits of doing this(my assumption) :
No more a need of _id column in the resultset.
Can fetch the data from database, put it into ArrayList and close the cursor.
No need of calling swapCursor() on each database operation as I can add/remove specify elements from the ArrayList and call notifyDataSetChanged()
I don't know the exact logic behind swapCursor() and notifyDataSetChanged(). So, can't decide which one is light-weight and efficient.
If someone has experienced this or done this before, please clear my doubts. Any corrections and suggestions are most welcome.
Using array list and custom adapter is better way for this as per my understanding.
See some scenarios below :
1) Cursor will close after each transaction so database will work smoothly.
2) As you can close cursor on operation done so it will never generate cursor not closed exception.
3) You can modify view of each row easily and manage custom adapter as per your choice.
There are many other reasons, but in short custom adapter is better then cursor adapter as per my understanding.
I have a ListView with attached custom CursorAdapter. Within the CursorAdapter bindView method I run some calculations that depend on user’s chosen display units (these can be changed at any time in Settings)
Normally to update a ListView I would run:
myCursor = DB.getData();
myDataAdapter.changeCursor(myCursor);
This works fine in most cases. But if user changed their display units in Settings, above code doesn’t update the ListView. I assume this is because data in the cursor hasn’t actually changed.
I tried running notifyDataSetInvalidated() and notifyDataSetChanged() against the adapter, also invalidateViews() against the ListView, but none of this make any difference.
What I currently do is recreate the adapter:
myCursor = db.getData();
myCursorAdapter = new myCursorAdapter(getActivity(),myCursor,0);
myListView.setAdapter(myCursorAdapter);
This works, but I don’t think it’s a good practice to re-create the adapter every time I need to refresh ListView... Is there a better way to do this?
EDIT:
myDataAdapter.changeCursor(myCursor) is actually working even when data in cursor hasn't changed. It was my own mistake in the Custom Cursor Adapter code that caused listview not to update unless adaptor was re-created.
notifyDataSetChanged() still doesn't work, but decided not to look into this further and just use changeCursor
The BaseAdapter method notifyDataSetChanged() should do what you want. It could be that the adapter you are passing in is not the same as the adapter the ListView is using. Try using getAdapter() instead:
((MyCursorAdapter) myListView.getAdapter()).notifyDataSetChanged();
I am really desperate, please help me.
In my main Activity I want to remove all items from the listview then add other data. I am able to delete the data and refresh the listview, but when I add new data, something strange happens. I insert the data in my Array. I call notifydatasetchanged on my adapter after every insertion. The adapter gets those items (I have confirmed this in debug mode). But the listview will not refresh. And now comes the VERY STRANGE thing: When I tap the back button on my device, the application quits (this part is ok), but for a moment before quitting it refreshes the listview with the correct data.
Here are some parts of my code:
For deleting the data I use:
newsArrayList = new ArrayList<NewsClass>();
Adapter = new NewsAdapter(this, newsArrayList);
lv.setAdapter(Adapter);
"lv" is my listview. The listview correctly loses all items and refreshes. I have also tried this:
newsArrayList.clear();
Adapter.notifyDataSetChanged();
Also worked like expected. Then I use a "for" loop to add new items to my array, where I have the following lines:
newsArrayList.add(news[i]);
Adapter.notifyDataSetChanged();
As I wrote, when running in debug mode, everything seems fine. I have spent all day working on this problem. I have read several posts about similar issues on stackoverflow, I even watched a video on youtube. I am calling everything from the main UI thread.
I can work around this problem by restarting my activity, but I want to do it better than that. I have tried invalidate and such things, but nothing helped. Please note the VERY STRANGE thing, I wrote...
I think, that I have to force the activity to redraw its views, or something like that, but even refreshDrawableState(); on my listview did not help.
Thank you in advance!
Basically If you want to clear list data then just call
newsArrayList.clear();
lv.setAdapter(null);
Again add what ever your data in ArrayList and set adapter
newsArrayList = new ArrayList<NewsClass>();
Adapter = new NewsAdapter(this, newsArrayList); // considering list with some elements
lv.setAdapter(Adapter);
If you are getting outofmemory error/exception then there is problem with your Adapter Class inside getView method
I am doing this:
// Member variable
List<String> items = null;
// in onCreate
items = new ArrayList<String>();
// later on in a Task (onPostExecute)
items.add(NewItem);
adapter.notifyDataSetChanged();
My List is in Alphabetical order. When I add an item, it simply puts it at the bottom. Any way to put it in the proper place?
(Yes it will be in proper order the second time you come back to this page, but not on adding it)
Edit: I am first putting it in order through a SQL script call.
My suggestion to your answer is that, as and when you add an item on ListView try to set the adapter again on the list at the time of adding item.
this way you get the refreshed data on your ListView.
I decided to research any methods for ArrayList and did not find any. I did find this, however:
items.add(NewItem);
Collections.sort(items);
Worked perfectly! I had to import Collections into the project.
I have a GridView backed by an ArrayAdapter. Everything works except for one thing: I couldn't clear that adapter (need this when refreshing the `GridView).
This is what I have:
adapter.clear();
adapter.notifyDataSetChanged();
Prior to this project I have never had any issue regarding adapter clearing. I can't find what I am doing wrong here.
Any idea? (don't hesitate to ask for specific details).
Thanks!
Problem solved.
I had to keep a reference on the collection that the adapter was taking its data from and then do:
myCollection.clean();
adapter.notifyDataSetChanged();