對於我的自定義適配器,我希望能夠過濾ListView中的項目。我實現了Filterable,並創建了一個Filter。Android:自定義過濾器不顯示結果,.clear()和.addAll()有
這裏是我的publishResults:
@Override
protected void publishResults(CharSequence constraint, FilterResults results)
{
MainActivity.this.filteredPetList.clear();
MainActivity.this.filteredPetList.addAll((ArrayList<Pet>)results.values);
notifyDataSetChanged();
}
如果我
MainActivity.this.filteredPetList.addAll((ArrayList<Pet>)results.values);
之後檢查filteredPetList,結果顯示正常,但該適配器將不會更新視圖。
任何想法我做錯了什麼?我可能再次做一些愚蠢的事情。
-Edit- 在我的適配器中,我重寫了notifyDataSetChanged,以查看它是否實際調用。它說:
@Override
public void notifyDataSetChanged()
{
System.out.println("Notified...");
super.notifyDataSetChanged();
}
我得到的結果,每當我試圖篩選,notifyDataSetChanged被調用。我還檢查了我的filteredPetList實際上是否在Filter之外進行了更改,並且是。
這只是意見不出於某種原因更新...
CNC中添加的全適配器代碼:
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();
}
}
}
提前感謝!
Tregan
請發佈您的適配器的完整代碼。 – Luksprog
完成。添加它作爲編輯。 – Tregan
這種行爲是正常的。你從'MainActivity'過濾和更新一個列表,但是你的整個適配器是基於你創建的一個全新列表'rows',所以過濾後的結果將不會被適配器看到。另外,我希望'ImageTextTextRow'不是某種行,而是將它存儲在該列表中,因爲這是一件壞事。 – Luksprog