列表适配器不会更新新项目

时间:2014-07-03 15:58:09

标签: android listview listadapter

目前我有一个使用无限列表加载实现的ListView,因为它会加载X个项目,然后当用户滚动到底部时,它会执行AsyncTask调用以加载更多项目,然后将它们加载到列表并更新它。目前这一切都在起作用,但问题在于,为了使其正常工作,必须以非常低效的方式完成,直到列表变长,将新项目加载到其中需要更长时间,因为整个列表是"替换"每一次,这显然是不可取的。以下是我在AsyncTask获得成功响应后,目前如何更新列表:

//this first line is what makes the loading so slow, but without it the list returns an empty set when calling notifyDataSetChanged() on the ListAdapter
TopPostFragment.postList = new ArrayList<Post>(TopPostFragment.postList);
TopPostFragment.postList.addAll(result); //result is the new items that were received from the AsyncTask
TopPostFragment.updateList();

显然第一行是完全没必要的,但出于某种原因,如果删除它,列表在适配器中没有正确更新,它将更新为空列表。我在TopPostFragment中的updateList()方法如下:

public static void updateList() 
    {   
        if(listAdapter != null)
        {
            listAdapter.clear();
            listAdapter.addAll(postList);
            listAdapter.notifyDataSetChanged();
        }
    }

我有一种感觉,问题可能会在某种程度上源于我在listAdapter中处理它的方式,所以这是我的ListAdapter的构造函数,关于我如何处理它:

List<Post> postList = null;

public PostListAdapter(Context context, int layoutResourceId, List<Post> list, int whichList, int currentFeedID) {
        super(context, layoutResourceId, list);
        postList = list;
    }

我删除了与此问题无关的所有代码中的行。如果我将列表复制到一个全新的列表中,列表只会更新的地方我做错了什么?

1 个答案:

答案 0 :(得分:0)

如果不能看到更多的代码,可能很难确定确切的问题。但作为我的工作实现的一个例子,你可以看看它是如何工作的。

通常作为经验法则,我从不初始化适配器中的列表以设置为任何其他列表。相反,我总是使用.add()或.addAll()或.remove()或.clear()等来确保对原始列表的引用永远不会丢失,并且您始终拥有相同列表的句柄适配器和列表视图。

所以搜索你的代码,并确保适配器中的列表初始化一次,并且只对其进行操作,并且永远不会将=设置为任何其他列表。

public class ItemAdapter extends BaseAdapter
{

    private final static int VIEWTYPE_PIC = 1;
    private final static int VIEWTYPE_NOPIC = 0;

    private List<Item> items;
    LayoutInflater layoutInflator;
    ActivityMain activity;

    public ItemAdapter(List<Item> items, LayoutInflater layoutInflator, ActivityMain activity)
    {
        super();
        this.items = new ArrayList<Item>();
        updateItemList(items);
        this.layoutInflator = layoutInflator;
        this.activity = activity;
    }

    public void updateItemList(List<Item> updatedItems)
    {
        if (updatedItems != null && updatedItems.size() > 0)
        {
            // FIND ALL THE DUPLICATES AND UPDATE IF NESSICARY
            List<Item> nonDuplicateItems = new ArrayList<Item>();
            for (Item newItem : updatedItems)
            {
                boolean isDuplicate = false;
                for (Item oldItem : items)
                {
                    if (oldItem.getId().equals(newItem.getId()))
                    {
                        // IF IT IS A DUPLICATE, UPDATE THE EXISTING ONE
                        oldItem.update(newItem);
                        isDuplicate = true;
                        break;
                    }
                }
                // IF IT IS NOT A DUPLICATE, ADD IT TO THE NON-DUPLICATE LIST
                if (isDuplicate == false)
                {
                    nonDuplicateItems.add(newItem);
                }
            }

            // MERGE
            nonDuplicateItems.addAll(items);
            // SORT
            Collections.sort(nonDuplicateItems, new Item.ItemOrderComparator());
            // CLEAR
            this.items.clear();
            // ADD BACK IN
            this.items.addAll(nonDuplicateItems);
            // REFRESH
            notifyDataSetChanged();
        }
    }

    public void removeItem(Item item)
    {
        items.remove(item);
        notifyDataSetChanged();
    }

    @Override
    public int getCount()
    {
        if (items == null)
            return 0;
        else
            return items.size();
    }

    @Override
    public Item getItem(int position)
    {
        if (items == null || position > getCount())
            return null;
        else
            return items.get(position);
    }

    @Override
    public long getItemId(int position)
    {
        return getItem(position).hashCode();
    }

    @Override
    public int getItemViewType(int position)
    {
        Item item = getItem(position);
        if (item.getPhotoURL() != null && URLUtil.isValidUrl(item.getPhotoURL()) == true)
        {
            return VIEWTYPE_PIC;
        }
        return VIEWTYPE_NOPIC;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        ItemHolder itemHolder;
        if (convertView == null)
        {
            if (getItemViewType(position) == VIEWTYPE_PIC)
            {
                convertView = layoutInflator.inflate(R.layout.item_pic, null);
            } else
            {
                convertView = layoutInflator.inflate(R.layout.item, null);
            }
                    // THIS CONSTRUCTOR ALSO CALLS REFRESH ON THE HOLDER FOR US
            itemHolder = new ItemHolder(convertView, position);
            convertView.setTag(itemHolder);
        } else
        {
            itemHolder = ((ItemHolder) convertView.getTag());
            itemHolder.refreshHolder(position);
        }
        return convertView;
    }

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

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

    @Override
    public boolean isEmpty()
    {
        return (getCount() < 1);
    }

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

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