notifyDataSetChanged() does not update the listview - android

I have a list of 4 items, I have used listview. I want to change a string dynamically on recieving internal event. I see that when I receive the event I am setting the string correctly but and then calling
mAdapter.notifyDataSetInvalidated();
mAdapter.notifyDataSetChanged();
but the list is not getting updated.

I've had the same experience. The cause was that the list adapter was updating on the wrong thread i.e. not the UI thread. This is easily solved by changing the adapter data on the UI thread through (as I found on other posts):
runOnUiThread(new Runnable() {
public void run() {
// code that changes the list adapter data
}
});
Of course you can always create a (inner) class that implements Runnable that is provided with the list adapter and data to add, insert etc.
Note: calling notifyDataSetInvalidated() or notifyDataSetChanged() will not be necessary as it is called by default, unless you turned it off explicitly with setNotifyOnChange(false);

I think that notifyDataSetChanged only works if you use the add (or insert), remove or clear functions on adapter.
You can rebuilt the list adapter for force to refresh the listView.
Excuse me for my bad english

Related

Notify dataset changed not fetching new data for the recyclerview

I have a recyclerview that is not updating and I am not sure why:
In my main fragment I get the data for the my recyclerview in oncreateview like this:
alarms = AlarmCollection.getAlarms(getActivity());
and then I set the adapter like this:
// Adapter
adapter = new AlarmsAdapter(getActivity(), alarms);
rv.setAdapter(adapter);
And then I reset the data on a timertask/runnable to update the values of on the recyclerview (they are alarms so they change once a minute).
This is done through a simple notify datasetchanged:
adapter.notifyDataSetChanged();
The problem is though as you can see above I load the data through AlarmCollection. This is grabbing the list from the shared preferences.
But when I am calling notify dataset changed this is not being called again.
I was under the impression that when you call notify ect on a recyclerview it would update the list or does it pureley update the view?
As #GpRyan mentioned, the problem lies in this line :
alarms = AlarmCollection.getAlarms(getActivity());
Every time you make a new instance of alarms.But the adapter is looking for changes in the instance of alarms you passed to it. so it won't work.
what you should do is removing all items from alarms and add your new data again.
alarms.removeAll();
alarms.addAll(AlarmCollection.getAlarms(getActivity()));
adapter.notifyDataSetChanged();
NOTE: Update the alarmsin your main thread. Once, it takes me a long time that i understand updating the data set in another thread
wont work with adapter.
notifyDataSetChanged() only updates the view. Typically what you'll do is call notifyDataSetChanged() after you've modified the data that the adapter holds (in your case alarms.
So what you should be doing is: updating alarms inside of your timer task / runnable, and then calling notifyDataSetChanged()
If your getItemCount() returns 0, then notifyDataSetChanged() won't do anything.
make sure you have added getItemCount() in your RecyclerView Adapter.
#Override
public int getItemCount() {
return alarms.size();
}
EDIT : you can also use notifyitemrangechanged
adapter.notifyItemRangeChanged(0,alarms.size());

Is notifyDataSetChanged() really necessary when updating ListView

I have a ListView with an adapter. I have only an ImageView-object on my ListViewItem. When I change the content of the Bitmaps in the ListViewItems, I always have to call adapter.notifyDataSetChanged(). Otherwise the Bitmaps are not refreshed. I already tried myImageView.Invalidate() on each ImageView in the Listview, but this doesn´t help.
Some Code for updating the ListViews:
runOnUiThread(new Runnable()
{
#Override
public void run()
{
Canvas myCanvas = rowItems.get(0).getCanvas();
// draw on canvas
adapter.notifyDataSetChanged();
}
});
Now my question: Is there an alternative to refresh the ListViews (in my case the content of the bitmaps) or do I have to call notifyDataSetChagend? Thanks!
The adapter needs to know that the data has changed in order to refresh itself so it's necessary to do so. The question is why you need an alternative in the first place!
However if you need it to be more performant you can notify the specific item got changed not the whole items by using RecyclerView.Adapter's notifyItemChanged (int position) and this is not available if you still using ListView.

Live Update ListView

I have dug deep down into SO but, although I have found other people asking similar questions to mine, I have not yet find a question that addresses the same issues I have. I have not found a satisfying answer either.
I have a ListView. When I call from the adapter, .notifyDataSetChanged, the ListView is updated, but I can see the update only once onResume() is called. In other words, I do not see it instantly, only after I leave the activity and comeback.
What can I do to see the update instantly? I have tried the .notifyDataSetChanged method, I have tried resetting the adapter... nothing worked.
According to your comment, you dont update the array IN the adapter, but an array held by the activity you passed to the adapter once. Thats why the adapter isnt updating properly. You are changing the array outside of your adapter-class, which might not be the same array-object your adapter is using. At onResume(), your adapter is recreated with the new array and showing the new content.
A solution would be using the following custom Adapter class:
class MyAdapter extends BaseAdapter {
private Array[] myArray;
public MyAdapter(Array[] myArray) {
this.myArray = myArray;
}
public updateContent(Array[] myNewArray) {
this.myArray = myNewArray;
this.notifyDataSetChanged();
}
// your getItem, getView, and so on methods
}
Then from your activity, simple call myArray.updateContent() with your new Array and it will update immediatly.
Its never good to hold and manipulate an object used from one class (the adapter) within another one (the activity). Try to move all code for manipulating the array into the adapter and use methods to add/remove items. This will make it a lot easier finding this kind of errors!

Update ListView from adapter Instantly

I'm developing an application that shows stock market information. In my application I use listactivity and my own adapter is being used.
The listView used to show the stocks is working fine and is updated with correct data. The only problem is, although I use
adapter.notifyDataSetChanged();
the list isn't updated until scrolling and items subjected to change, are scrolled out from the screen. When they are scrolled in, they appear with new data.
I need to change the data as soon as I notify the adapter.
I have face same problem
but finally got solution
And its solution is
listView.invalidateViews();
I think for that you have to take the help of the Lazy ListView or Lazy Loader:
Check out the below link :
Lazy load of images in ListView
It will help you.
Are you calling notifyDataSetChanged in UI thread? If not: you can do the following:
runOnUiThread(new Runnable() {
public void run() {
adapter.notifyDataSetChanged();
}
});

Android: Possible solution for updating the custom list view at random times

I am having a situation where I want to update my Custom List View using BaseAdapter whenever my Database is updated. I have tried calling invalidate() on this Custom List but it didn't work, similarly I even tried having a timer to update my list after sometime, that didn't work either. Please let me know of possible solution.
Update:
This is how I am making my custom list view
li= (ListView)findViewById(R.id.id_lv_row);
ColorDrawable divcolor = new ColorDrawable(Color.DKGRAY);
registerForContextMenu(li);
li.setDivider(divcolor);
li.setDividerHeight(2);
li.setAdapter(new FriendsPositionAdapter(this));
BaseAdapter.notifyDataSetChanged() should do the trick as long as the data behind the adapter actually changed. That's all you need to do to refresh the list.
Invalidate is for repainting views only, you have to tell to the List adapter (BaseAdapter) that dataset has changed.
When the data changes, asign the new dataset to the adapter, and later call notifyDataSetChanged()...
in order to make functional notifyDataSetChanged() the adapter data must be changed. Remember that the original data that change is not reflected automatically to the adapter.
//here i retrieve the new list, named "beans"
lista = (BeanList) result.getDataObject();
Vector<Bean>beans = list.getBeanList();
((BeanListAdapter)listAdapter).syncData(beans);
((BeanListAdapter)listAdapter).notifyDataSetChanged();
//now the syncData method
public void syncData( List<PINPropiedad> newData ){
for(Object o : newData){
add(o);
}
}

Categories

Resources