johng
johng

Reputation: 1026

notifyDataSetChanged not working with arraylist datatype

I know this question has been asked a lot, however I have spent a long time going through all q/a and nothing has solved the issue.

My application has data fetched periodically from an AsyncTask which is started by a Service class. OnProgressUpdate on the Async Task calls the broadcast which the main activity is listening for. The data is fetched from the intent.

On the main actitivity I declare the arraylist globally.

private  ArrayList<HashMap<String, String>> askOrder = new ArrayList<HashMap<String, String>>();

I then set the adapter with null data on the oncreateview.

ListView listVask = (ListView) myFragmentView.findViewById(R.id.listViewAsk);
adapterAsk = new askOrderAdapter(getActivity(),askOrder);
listVask.setAdapter(adapterAsk);

When the broadcast on the asynctask has new data it will call sendbroadcast. For which the updateUI method is registed to. The data has been put in the intent. I have checked

 public void updateUI(Intent intent){
     askOrder = (ArrayList<HashMap<String, String>>) intent.getExtras().get("askOrder");
     listVask = (ListView) myFragmentView.findViewById(R.id.listViewAsk);
     ((BaseAdapter) listVask.getAdapter()).notifyDataSetChanged();

So when called the notifyDataSetChanged does not update the adapter to get the new data in the arraylist askOrder

I previously had this working when I had the application logic changed. I had a separate class data to store all the data. The asynctask would write the data to that class and the data would be stored as a static variable. It would then notify the MainActivity to recheck for the data. The MainActivity would then update the variable askOrder like below.

With orderbookData being the class file with the stored data in.

askOrder = orderbookData.askOrder;

Upvotes: 2

Views: 202

Answers (1)

Darth Beleg
Darth Beleg

Reputation: 2667

The problem is that you don't change the contents of the adapter so calls to notifyDataSetChanged are meaningless - there is no new data to represent.

It seems that you may misunderstand the semantics of notifyDataSetChanged. Usually it doesn't mean 'hey, adapter, your underlying data has been changed, update yourself' (you can implement it that way but I don't recommend it). It means that the adapter's content has been changed already so observers of this adapter (like listview) must be notified about a change to take actions for displaying new data. So you should rarely call this method outside of the adapter. The only case where such external call may be applicable is when adapter's internal data structure is shared (may be adapter just stores a reference to a provided list inside and this list is modified externally then). But this approach may lead to subtle issues.

For your task I recommend to introduce a new method to your adapter class, something like setData(ArrayList<HashMap<String, String>> newData) that will update underlying adapter's data structure and internally call notifyDataSetChanged after that. The ListView that your adapter is associated with will reask for updated views as a result and the adapter should provide these views based on the updated internal data.

void updateUI() {
 askOrder = (ArrayList<HashMap<String, String>>) intent.getExtras().get("askOrder");
 listVask = (ListView) myFragmentView.findViewById(R.id.listViewAsk);
 ((askOrderAdapter) listVask.getAdapter()).setData(askOrder);
}

Upvotes: 2

Related Questions