6

I'm using ArrayAdapter to bind my data from my ArrayListto my ListView and i use an AlertDialogto insert data into my Arraylist. My problem is that i'm unable to refresh my ListView after the changes done.

Code

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.config_hidden);
    listView=(ListView) findViewById(R.id.hiddenList);
    xmlFileManager=new XmlFileManager(this);
    addNumber=(Button) findViewById(R.id.addNum);

    addNumber.setOnClickListener(new OnClickListener() {

        public void onClick(View arg0) {

            LayoutInflater factory = LayoutInflater.from(HiddenCall.this);
            final View alertDialogView = factory.inflate(R.layout.add_number, null);
            AlertDialog.Builder adb = new AlertDialog.Builder(HiddenCall.this);
            adb.setView(alertDialogView);
            adb.setTitle(R.string.dialog_title);
            adb.setIcon(R.drawable.phone);

            final AlertDialog alertDialog = adb.create();

            adb.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    numberToAdd=(EditText) alertDialogView.findViewById(R.id.numberToAdd);
                    String number = numberToAdd.getText().toString();
                    if(number.length()>0){
                        xmlFileManager.addNumberToXml(number , HIDDEN_NUMBER_TYPE);
                        adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, xmlFileManager.getHiddenNumbers());
                        adapter.setNotifyOnChange(true);
                        adapter.notifyDataSetChanged();
                    }
                } });

            adb.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    alertDialog.dismiss();
                } });
            adb.show();
        }
    });
    adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, xmlFileManager.getHiddenNumbers());
    adapter.notifyDataSetChanged();
    adapter.setNotifyOnChange(true);
    listView.setAdapter(adapter);
}
3
  • why are you creating a new adapter each time instead of modifying the existing one? your calls to notifyDataSetChanged() are useless if you just created the adapter.. Commented Aug 2, 2012 at 21:32
  • Another thing I see you are missing is to set the adapter to the listview... Commented Aug 2, 2012 at 22:05
  • I posted the code, hope it helps. You still need to add some sort of setter to the adapter and pass there the updated data. Commented Aug 2, 2012 at 22:09

4 Answers 4

8

You are instantiating a new adapter each time. What you have to do is put the line where you instantiate the adapter before the click listener, and in the click listener modify that adapter and call notifyDataSetChanged() on it. You of course have to add some setters to your adapter in order to modify the data.

Has to look similar to this:

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.config_hidden);
listView=(ListView) findViewById(R.id.hiddenList);

//instantiate the adapter (just one time)
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, xmlFileManager.getHiddenNumbers());

//assign the adapter to the listview
listView.setAdapter(adapter);

xmlFileManager=new XmlFileManager(this);
addNumber=(Button) findViewById(R.id.addNum);

addNumber.setOnClickListener(new OnClickListener() {

    public void onClick(View arg0) {

        LayoutInflater factory = LayoutInflater.from(HiddenCall.this);
        final View alertDialogView = factory.inflate(R.layout.add_number, null);
        AlertDialog.Builder adb = new AlertDialog.Builder(HiddenCall.this);
        adb.setView(alertDialogView);
        adb.setTitle(R.string.dialog_title);
        adb.setIcon(R.drawable.phone);

        final AlertDialog alertDialog = adb.create();



        adb.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                numberToAdd=(EditText) alertDialogView.findViewById(R.id.numberToAdd);
                String number = numberToAdd.getText().toString();
                if(number.length()>0){
                    xmlFileManager.addNumberToXml(number , HIDDEN_NUMBER_TYPE);
                    //adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, xmlFileManager.getHiddenNumbers());
                    //adapter.setNotifyOnChange(true);

                    //set the changed data
                    adapter.setData(xmlFileManager.getHiddenNumbers());

                    //notify that the model changed
                    adapter.notifyDataSetChanged();
                }
            } });

        adb.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                alertDialog.dismiss();
            } });
        adb.show();
    }
});

//adapter.notifyDataSetChanged();
//adapter.setNotifyOnChange(true);
Sign up to request clarification or add additional context in comments.

5 Comments

@lxx ArrayAdapterdoesn't have the method setData
Ah, yes, you actually don't have to set the data in the ArrayAdapter. It should be enough to update the underlying array, which you are already doing addNumberToXml(). So just remove the setData() line. Tell me if that works.
I assume the hidden numbers array passed to the xmlFileManager is always the same. If the instance is created again the changes will not be noticed by the adapter.
I tried to call notifyDataSetChangedbut it seems it doesn't take the change in consideration. To resolve this problem i preferred create a ListAdapterthat extends BaseAdapter and now it's working. Thanks for your reply .
Yes, that was the plan B which I was going to tell you if you say me that the array adapter doesn't show the changes. You should post the complete code, there's no way to know if the array you're passing is always the same reference or not. And anyways, this answer shows you the principle of using an adapter (also applies for custom adapter) and I deserve at least +1. No way to tell you the exact solution if you don't post complete code.
4

If you have a small ArrayList, to force update a ListView when the ArrayList changes you can use this code snippet:

ArrayAdapter.clear();
ArrayAdapter.addAll(ArrayList);
ArrayAdapter.notifyDataSetChanged();

1 Comment

What do you mean by "small"? It looks ok even for large lists (10 000 items). Of course it is not a good practise to refresh the whole list after updating only one item (for example). The app architecture made me to use it for now. :-)
0

Every click you create new adapter. You don't need to do this. You can modify existing adapter data and call notifyDataSetChanged(). In your case you should call listView.setAdapter(adapter) in onClick method.

2 Comments

@lxx shouldn't he set the adapter in onCreate() and just modify it in onClick() ?
That's what I'm saying, create and set once, and modify in onClick() (and call notifyDataSetChanged()).
0

Inside your adb.setPositiveButton()'s onClick(), you should not create a new adapter. Remove this line:

adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, xmlFileManager.getHiddenNumbers());

Simply do this:

if(number.length()>0){
    xmlFileManager.addNumberToXml(number , HIDDEN_NUMBER_TYPE);
    adapter.notifyDataSetChanged();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.