2

I have an array: Object[] array, and an array adapter that extends ArrayAdapter<Object>. When i try to delete from it using adapter.remove(Object obj) i get an UnsupportedOperationException exception, just as this post. The provided answers suggest using an ArrayList instead. This is not an option for me. I need to stick with array. So i copied the array to another array, but without the item i want to delete. Then i just did:

oldArray = newArray;

and then called adapter.notifyDataSetChanged();.

This works fine except it doesn't refresh the screen. I need to close then reopen the screen to see the changes. Shouldn't notifyDataSetChanged() do the refreshing?

edit:

Following @MD's answer, this is what i'm doing right now:

controller.onRemove(id);

public void onRemove(int id) {
    int userListLength = usersArray.length;
    int j = 0;
    User[] newUserList = new User[userListLength-1];
    for(int i=0; i<userListLength; i++)
    {
        if(id != usersArray[i].getId())
        {
            newUserList[j] = new User();
            newUserList[j] = usersArray[i];
            j++;
        }
    }
    usersArray = newUserList;
    //store in database
    //...
    view.getAdapter().refresh( usersArray );
}

public void refresh(User[] items)
{
    this.userArray = items;
    notifyDataSetChanged();
}

adapter construction:

adapter = new myUserAdapter( controller.getBaseContext(), R.layout.user_row, userArrayList);
usersListView.setAdapter( adapter );

and in myUserAdapter i have:

private User[]  userArray;

Solution:

@MD's answer works. But I also had to override getCount() in the adapter:

@Override
public int getCount () {
    return userArray.length;
}

It's explained in the accepted answer here.

Community
  • 1
  • 1
Alaa M.
  • 4,961
  • 10
  • 54
  • 95

2 Answers2

2

i have a way

Add refresh method in your adapter:

public void refresh(List<String> items)
{
    this.items = items;
    notifyDataSetChanged();
}

and call from Activity like

yourAdapter.refresh(items); // items new arrayList or Array
M D
  • 47,665
  • 9
  • 93
  • 114
  • Calling `notifyDataSetChanged()` this way gives an exception: AndroidRuntime(15393): java.lang.RuntimeException: Unable to start activity – Alaa M. Mar 29 '15 at 07:58
  • I think, keeping an extra `items` field in the class that extends ArrayAdapter wasn't meant by the authors – basin Mar 29 '15 at 08:15
  • `notifyDataSetChanged()` now gives an `ArrayIndexOutOfBoundsException` somehow – Alaa M. Mar 29 '15 at 08:39
  • 1
    OK it works now! I overridden `getCount()` in my adapter. I'll put explanation in my question. – Alaa M. Mar 29 '15 at 08:44
0

ArrayAdapter simply wraps the List<T> you pass to its constructor and when you call remove(), it calls the remove() method of that list.

If you pass an array instead of a list to the constructor, it converts it with Arrays.asList().

/**
 * Constructor
 *
 * @param context The current context.
 * @param resource The resource ID for a layout file containing a TextView to use when
 *                 instantiating views.
 * @param objects The objects to represent in the ListView.
 */
public ArrayAdapter(Context context, int resource, T[] objects) {
    init(context, resource, 0, Arrays.asList(objects));
}

In older Android versions Arrays.asList returns a readonly list. That's why you get the exception

You must explicitly create an ArrayList out of your array:

adapter = new myUserAdapter( controller.getBaseContext(), R.layout.user_row, new ArrayList<User>(Arrays.asList(userArrayList)));
basin
  • 3,949
  • 2
  • 27
  • 63
  • @AlaaM. why? Are you planning to modify that array? The adapter won't reflect the changes anyway – basin Mar 29 '15 at 08:44