ListView с пользовательским адаптером не будет обновляться при обновлении содержимого - PullRequest
2 голосов
/ 03 ноября 2011

У меня есть один собственный ListView под названием AreasListView, который я включил в файл XML. Единственное, что отличает это от ListView, это следующие строки кода:

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);
}

Нижний колонтитул добавляется самим списком в конструкторе.

К этому списку я устанавливаю пользовательский адаптер в методе onCreate. Позже (когда пользователь нажимает на нижний колонтитул, который имеет пользовательское представление списка), запускается другое действие для результата. Когда тот возвращает, новый элемент добавляется в ArrayList, который находится под пользовательским адаптером.

Вот код адаптера:

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;
}

}

После получения результата я пытаюсь вызвать notifyDataSetChanged, но он не работает. Код:

    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();
        }

Что я делаю не так? До сих пор я пробовал следующее:

  • измените AreasListView, чтобы я не получил HeaderListViewAdapter и попытался вызвать notifyDataSetChanged ();
  • call list.invalidate ();
  • call list.invalidateViews ();
  • call list.requestLayout ();

UPDATE: Я пытался использовать решение @ Джек, и оно не работает. Вот что я сделал: из моего 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);
            }

и соответствующий код от AreasAdapter:

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

Ответы [ 4 ]

1 голос
/ 07 ноября 2011

Я исправил проблему.Очевидно, что нужно было удалить метод @Override setAdapter из моего пользовательского списка.

Это странно, поскольку все, что в нем содержалось, - это вызов super.setAdapter (адаптер).

0 голосов
/ 03 ноября 2011

Пожалуйста, посмотрите этот ответ, так как я думаю, что он укажет вам правильное направление.Он в основном говорит:

Для ArrayAdapter notifyDataSetChanged работает, только если вы используете функции добавления, вставки, удаления и очистки адаптера.

РЕДАКТИРОВАТЬ: см. Также это фрагмент кода.Они добавляют вызов notifyDataSetChanged () к адаптеру:

       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();
        }
0 голосов
/ 03 ноября 2011

Попробуйте list.requestLayout (), он помог мне с TextView и как в документации

«Вызывайте это, когда что-то изменилось, что сделало недействительным макет этого представления»

0 голосов
/ 03 ноября 2011

Попробуйте позвонить:

list.invalidate();
...