目前我有一个使用无限列表加载实现的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;
}
我删除了与此问题无关的所有代码中的行。如果我将列表复制到一个全新的列表中,列表只会更新的地方我做错了什么?
答案 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;
}
}