【发布时间】:2013-07-26 16:14:26
【问题描述】:
对于我的自定义适配器,我希望能够过滤 ListView 中的项目。我实现了 Filterable,并创建了一个 Filter。
这是我的发布结果:
@Override
protected void publishResults(CharSequence constraint, FilterResults results)
{
MainActivity.this.filteredPetList.clear();
MainActivity.this.filteredPetList.addAll((ArrayList<Pet>)results.values);
notifyDataSetChanged();
}
如果我在之后检查filteredPetList
MainActivity.this.filteredPetList.addAll((ArrayList<Pet>)results.values);
,结果显示正常,但适配器不会更新视图。
任何想法我做错了什么?我可能又在做一些愚蠢的事情了。
-编辑- 在我的适配器中,我覆盖了 notifyDataSetChanged,以查看它是否实际被调用。它说:
@Override
public void notifyDataSetChanged()
{
System.out.println("Notified...");
super.notifyDataSetChanged();
}
每当我尝试过滤时,都会得到一个结果,notifyDataSetChanged 会被调用。我还检查了我的 filteredPetList 是否真的在 Filter 之外被更改了,确实如此。
只是视图由于某种原因没有更新......
-Edit- 添加完整的适配器代码:
private class PetAdapter extends BaseAdapter implements Filterable
{
private final Object lock = new Object();
List<Row> rows;
ArrayList<Integer> petIds;
boolean clickable;
PetFilter petFilter;
public PetAdapter(ArrayList<Pet> petList, boolean clickable)
{
this.clickable = clickable;
rows = new ArrayList<Row>();
this.petIds= new ArrayList<Integer>();
for(Pet p : petList)
{
rows.add(new ImageTextTextRow(LayoutInflater.from(MainActivity.this), p.getPetImageId(), p.getPetName(), p.getPetFood()));
petIds.add(p.getPetId());
}
}
@Override
public boolean isEnabled(int position)
{
//Can do that certain items ARE enabled by using the position
return clickable;
}
@Override
public int getViewTypeCount()
{
return RowType.values().length;
}
@Override
public int getItemViewType(int position)
{
return rows.get(position).getViewType();
}
@Override
public int getCount()
{
return rows.size();
}
@Override
public Object getItem(int position)
{
return rows.get(position);
}
@Override
public long getItemId(int position)
{
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
return rows.get(position).getView(convertView);
}
/**
*
* @param position
* @return
*/
public int getSelectedPetId(int position)
{
return petIds.get(position);
}
@Override
public Filter getFilter()
{
if (petFilter == null)
petFilter = new PetFilter();
return petFilter;
}
private class PetFilter extends Filter
{
@Override
protected FilterResults performFiltering(CharSequence constraint)
{
FilterResults results = new FilterResults();
if (MainActivity.this.filteredPetList == null)
{
synchronized (PetAdapter.this.lock)
{
MainActivity.this.filteredPetList = new ArrayList<Pet>(MainActivity.this.originalPetList);
}
}
if (constraint == null || constraint.length() == 0)
{
synchronized (PetAdapter.this.lock)
{
results.values = MainActivity.this.originalPetList;
results.count = MainActivity.this.originalPetList.size();
}
}
else
{
String constraintString = constraint.toString().toLowerCase(Locale.ENGLISH);
final ArrayList<Pet> items = MainActivity.this.filteredPetList;
final int count = items.size();
final ArrayList<Pet> newItems = new ArrayList<Pet>(count);
for (int i = 0; i < count; i++)
{
final Pet item = items.get(i);
final String itemName = item.getPetName().toLowerCase(Locale.ENGLISH);
if (itemName.startsWith(constraintString))
{
newItems.add(item);
}
else
{
final String[] words = itemName.split(" ");
final int wordCount = words.length;
for (int k = 0; k < wordCount; k++)
{
if (words[k].startsWith(constraintString))
{
newItems.add(item);
break;
}
}
}
}
results.values = newItems;
results.count = newItems.size();
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results)
{
MainActivity.this.filteredPetList.clear();
MainActivity.this.filteredPetList.addAll((ArrayList<Pet>)results.values);
if (results.count > 0)
PetAdapter.this.notifyDataSetChanged();
else
PetAdapter.this.notifyDataSetInvalidated();
}
}
}
提前致谢!
特里根
【问题讨论】:
-
请发布您的适配器的完整代码。
-
完成。将其添加为编辑。
-
行为正常。您从
MainActivity过滤和更新列表,但您的整个适配器基于您创建的全新列表rows,因此适配器不会看到过滤的结果。另外,我希望ImageTextTextRow不是某种行,并且您将其存储在该列表中,因为这样做是一件坏事。 -
一个问题不应该包含它的解决方案。如果您找到自己问题的答案,则应将其写为答案。这是鼓励的,假设您对帮助您的其他答案给予了适当的评价。
-
在
getView()方法中创建自定义视图。有一个名为The world of ListView的 google i/o 视频,您应该观看它以了解更多详细信息。