Usama Sarwar Usama Sarwar - 19 days ago 10
Android Question

ArrayAdapter.NotifyDataSetChanged() is not working?

I have a list that can be updated by the user, but

notifyDataSetChanged()
is not working on the adapter associated with the
listView
. I am using it in a fragment. Datbase gets updated, however the adpater doesn't. Following is my implementation:

My Main Fargment:

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myArrayList = new ArrayList<myList>();
myArrayList = Database.getSharedObject(getActivity()).getMyList();
if (myArrayList != null && myArrayList.size() > 0) {
adapter = new myListAdapter(getActivity(), 0, myArrayList);
}

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

View v = inflater.inflate(R.layout.mainfragment, container, false);
myListView = (ListView) v.findViewById(R.id.my_list_view);
myListView.setOnItemClickListener(this);
if (adapter != null) {
myListView.setAdapter(adapter);
}

return v;
}


After some navigations process List gets updated and in my
onResume()
method I get the updated List from database and call
notifyDatasetChanged()
method that does not update my view, however corresponding array from DB is updated one.

@Override
public void onResume() {
super.onResume();
myArrayList = Database.getSharedObject(getActivity()).getMyList();
adapter.setItems (myArrayList);
adapter.notifyDataSetChanged();

}


MyListAdapter

public class MyListAdapter extends ArrayAdapter<Message> {

private ArrayList<Message> myList;

/* Context */
private Context context;

public void setItems (ArrayList<Message> myList) {
this.myList = myList;
}

public MyListAdapter (Context context, int textViewResourceId, ArrayList<Message> myList) {
super(context, textViewResourceId, myList);
this.context = context;
this.myList = myList;
}

@Override
public View getView (int position, View v, ViewGroup parent) {
// Keeps reference to avoid future findViewById()
MyViewHolder viewHolder;

if (v == null) {
LayoutInflater li = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = li.inflate(R.layout.list_row, parent, false);

viewHolder = new MyViewHolder();
viewHolder.txtImage = (ImageView) v.findViewById(R.id.message_icon);
viewHolder.txtMessage = (TextView) v.findViewById(R.id.message);
viewHolder.txtDate = (TextView) v.findViewById(R.id.date);

v.setTag(viewHolder);
} else {
viewHolder = (MyViewHolder) v.getTag();
}

Message myMessage = new Message();
myMessage = myList.get(position);
if (myMessage != null) {
viewHolder.txtMessage.setText(myMessage.getText());
viewHolder.txtDate.setText(myMessage.getDate());
}
return v;
}

static class MyViewHolder {
ImageView txtImage;
TextView txtMessage;
TextView txtDate;
}
}


Any thought on what is going wrong? Why is not listview getting updated? Any helps is appreciated.

Answer

notifyDataSetChanged() won't work for you. Reasons why

  1. Your adapter loses reference to your list.
  2. Always creating and adding a new list to the Adapter. Do like this: initialize the ArrayList while declaring globally.

    ArrayList<myList> myArrayList=new ArrayList<myList>(); // as a global variable

    Add List to the adapter directly with out checking null and empty condition. Set the adapter to the list directly(don't check for any condition)

    myListView.setAdapter(adapter);

  3. Add data to the myArrayList Every time(if your data is completely new than you can call adapter.clear() and myArrayList.clear() before actually adding data to the list) but don't set the adapter i.e If the new data is populated in the myArrayList than just adapter.notifyDataSetChanged()

    adapter = new myListAdapter(getActivity(), 0, myArrayList);
    
  4. Remove this line

    adapter.setItems (myArrayList);