user552400
user552400

Reputation:

ListView with custom adapter won't update when contents updates

I have one custom ListView called AreasListView which I've included in the XML file. The only things that differentiate this from a ListView are the following lines of code:

private void setFooter(){
    LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View footer = inflater.inflate(R.layout.areas_list_add_item, null);
    addFooterView(footer);
}

@Override
public void setAdapter(ListAdapter adapter)
{
    super.setAdapter(adapter);
}

The footer is added by the list itself in the constructor.

To this list I am setting a custom adapter in the onCreate method. Later on (when the user clicks on the footer that the custom list view has) another activity is started for result. When that one returns a new item is added to the ArrayList that sits under the custom adapter.

Here's the adapter code:

public class AreasAdapter extends BaseAdapter

{

private Manager manager;

public AreasAdapter(Manager mgr){
    this.manager = mgr;
}

@Override
public int getCount()
{
    return manager.getAreas().size();
}

@Override
public Object getItem(int arg0)
{
    return manager.getAreas().get(arg0);
}

public Area getArea(int index){
    return manager.getAreas().get(index);
}

@Override
public long getItemId(int arg0)
{
    return arg0;
}

@Override
public int getItemViewType(int arg0)
{
    return Adapter.IGNORE_ITEM_VIEW_TYPE;
}

@Override
public View getView(int arg0, View arg1, ViewGroup arg2)
{
    AreasListItem viewToReturn = null;
    if (arg1 != null){
        viewToReturn = (AreasListItem)arg1;
    } else {
        LayoutInflater inflater = (LayoutInflater) arg2.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        viewToReturn = (AreasListItem)inflater.inflate(R.layout.areas_list_item, null);
    }
    viewToReturn.setArea(manager.getAreas().get(arg0));
    return viewToReturn;
}

@Override
public int getViewTypeCount()
{
    return 1;
}

@Override
public boolean hasStableIds()
{
    return false;
}

@Override
public boolean isEmpty()
{
    return (manager.getAreas().size() == 0);
}

@Override
public void registerDataSetObserver(DataSetObserver arg0)
{
    super.registerDataSetObserver(arg0);
}

@Override
public void unregisterDataSetObserver(DataSetObserver observer)
{
          super.unregisterDataSetObserver(observer);

}

@Override
public boolean areAllItemsEnabled()
{
    return true;
}

@Override
public boolean isEnabled(int position)
{
    return true;
}

}

After I receive the result I try to call notifyDataSetChanged, but it doesn't work. Code:

    if (resultCode == Activity.RESULT_OK){
            Area resultArea = (Area) returnIntent.getExtras().get(ActivityAreaAdd.EXTRA_AREA);
                service.getManager().addArea(resultArea);
//              TODO figure out how to update the list with the newly added areas
                ((AreasAdapter)(((HeaderViewListAdapter) list.getAdapter()).getWrappedAdapter())).notifyDataSetChanged();
        }

What is it that I am doing wrong? I've tried the following so far:


UPDATE: I tried using @Jack's solution and it doesn't work. Here's what I did: from my onActivityResult:

    if (resultCode == Activity.RESULT_OK){
            Area resultArea = (Area) returnIntent.getExtras().get(ActivityAreaAdd.EXTRA_AREA);
//              TODO figure out how to update the list with the newly added areas
                ((AreasAdapter)(((HeaderViewListAdapter) list.getAdapter()).getWrappedAdapter())).addArea(resultArea);
            }

and the corresponding code from AreasAdapter:

public void addArea(Area a){
    manager.addArea(a);
    notifyDataSetChanged();
}

Upvotes: 2

Views: 4951

Answers (4)

user552400
user552400

Reputation:

I fixed the problem. Apparently what was needed was to remove the @Override setAdapter method from my custom list.

It is weird, since all it contained was a call to super.setAdapter(adapter).

Upvotes: 1

Jack
Jack

Reputation: 9242

Please see this answer as I think it will point you in the right direction. He basically says:

For an ArrayAdapter, notifyDataSetChanged only works if you use the add, insert, remove, and clear functions on the Adapter.

EDIT: Also see this snippet of code. They add the notifyDataSetChanged() call to the adapter:

       public void clearPhotos() {
            mPhotos.clear();
            notifyDataSetChanged();
        }

        public void addPhotos() {
            int whichPhoto = (int)Math.round(Math.random() * (mPhotoPool.length - 1));
            int newPhoto = mPhotoPool[whichPhoto];
            mPhotos.add(newPhoto);
            notifyDataSetChanged();
        }

Upvotes: 0

Mateusz
Mateusz

Reputation: 2317

Try list.requestLayout() it helped me with TextView and as in documentation

"Call this when something has changed which has invalidated the layout of this view"

Upvotes: 0

Mathieu de Brito
Mathieu de Brito

Reputation: 2696

Try calling :

list.invalidate();

Upvotes: 0

Related Questions