【问题标题】:ListView with custom adapter won't update when contents updates内容更新时,带有自定义适配器的 ListView 不会更新
【发布时间】:2011-11-03 13:25:01
【问题描述】:

我有一个名为 AreasListView 的自定义 ListView,已包含在 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();
  • 调用 list.invalidate();
  • 调用 list.invalidateViews();
  • 调用list.requestLayout();

更新: 我尝试使用@Jack 的解决方案,但它不起作用。这是我所做的: 来自我的 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();
}

【问题讨论】:

  • 您的结果是否返回了正确的 RESULT_OK 的 result_code?​​span>
  • 是的。是的,我一直在调试它,它返回了 Area 和 RESULT_OK。
  • 什么是 HeaderViewListAdapter?
  • AreasList 为其自身添加了一个页脚。显然,当将页眉或页脚添加到列表时,ListView(它扩展)用 HeaderViewList 适配器包装其适配器。我认为可能是导致问题的原因,但我不知道如何解决。

标签: android android-listview listadapter


【解决方案1】:

我解决了这个问题。显然需要从我的自定义列表中删除 @Override setAdapter 方法。

这很奇怪,因为它只包含对 super.setAdapter(adapter) 的调用。

【讨论】:

    【解决方案2】:

    尝试调用:

    list.invalidate();
    

    【讨论】:

      【解决方案3】:

      试试 list.requestLayout() 它在 TextView 和文档中帮助了我

      “当某些事情发生变化而导致该视图的布局无效时调用它”

      【讨论】:

        【解决方案4】:

        请参阅this 答案,因为我认为它会为您指明正确的方向。他基本上说:

        对于 ArrayAdapter,notifyDataSetChanged 仅在您使用 在 Adapter 上添加、插入、删除和清除功能。

        编辑:另见thissn-p 代码。他们将 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();
                }
        

        【讨论】:

        • 你是如何实现的?您现在是否正在使用适配器添加项目?它出错了吗?您能否准确地发布您现在是如何添加项目的(如果需要,来自其他活动的代码示例)。
        • 来自我的 onActivityResult: ((AreasAdapter)(((HeaderViewListAdapter) list.getAdapter()).getWrappedAdapter())).addArea(resultArea);
        • 来自AreasAdapter: public void addArea(Area a){ manager.addArea(a); notifyDataSetChanged(); }
        • 请附加您的原始问题,在 cmets 中很难破译代码。
        猜你喜欢
        • 2015-05-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多