Фильтр поиска ListView оставляет нежелательные данные

У меня есть проблема с фильтром поиска в моем ListView. Когда я набираю буквы из моих объектов в поисковый ящик, он обычно ищет. Но когда я добавляю что-то еще, элементы остаются в ListView, несмотря на то, что он не содержит этот текст. Вы можете видеть это на картинке.

У вас есть идея, как это решить?

Адаптер с классом фильтра (ниже):

public class AnimalAdapter extends ArrayAdapter<animal> implements Filterable{
 private Context mContext;
 private List<animal> mAnimals;
 ImageLoader imageLoader;
 DisplayImageOptions options;
 Activity activity;
 AnimalAdapter adapter;
 private Filter animalFilter;
 private List<animal> animaly;
 ListView mListView;
 RelativeLayout row;

 @SuppressWarnings("deprecation")
 public AnimalAdapter(Context context, List<animal> objects) {
 super(context, R.layout.animal_row_item, objects);


 ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context).build();

 imageLoader = ImageLoader.getInstance();
 imageLoader.init(config);
 options = new DisplayImageOptions.Builder()
 .cacheInMemory()
 .cacheOnDisc()
 .build();

 this.mContext = context;
 this.mAnimals = objects;
 this.animaly = objects;

 }

 public View getView(int position, View convertView, ViewGroup parent){
 if(convertView == null){
 LayoutInflater mLayoutInflater = LayoutInflater.from(mContext);
 convertView = mLayoutInflater.inflate(R.layout.animal_row_item, null);
 }


 final Animal animal = mAnimals.get(position);


 TextView animalView = (TextView) convertView.findViewById(R.id.animal_text);
 TextView areaView = (TextView) convertView.findViewById(R.id.area_text);

 final ImageView animalPic = (ImageView)convertView.findViewById(R.id.animal_pic);
 final ProgressBar indicator = (ProgressBar)convertView.findViewById(R.id.progress);

 indicator.setVisibility(View.VISIBLE);
 animalPic.setVisibility(View.INVISIBLE);

 //Setup a listener we can use to switch from the loading indicator to the Image once it ready
 ImageLoadingListener listener = new ImageLoadingListener(){



 @Override
 public void onLoadingStarted(String arg0, View arg1) {
 // TODO Auto-generated method stub

 }

 @Override
 public void onLoadingCancelled(String arg0, View arg1) {
 // TODO Auto-generated method stub

 }

 @Override
 public void onLoadingComplete(String arg0, View arg1, Bitmap arg2) {
 indicator.setVisibility(View.INVISIBLE);
 animalPic.setVisibility(View.VISIBLE);
 }

 @Override
 public void onLoadingFailed(String arg0, View view, FailReason arg2) {


 }

 };

 imageLoader.displayImage(animal.getImgUrl(), animalPic,options, listener);
 animalView.setText(animal.getAnimal());
 areaView.setText(animal.getArea());


 convertView.setOnClickListener(new OnClickListener() {

 @Override
 public void onClick(View view) {

 Intent intent = new Intent(getContext(), MoreActivity.class);

 intent.putExtra("about", animal.getAbout());
 intent.putExtra("animal", animal.getAnimal());
 intent.putExtra("imgUrl", animal.getImgUrl());
 getContext().startActivity(intent);
 }
 });

 return convertView;
 }




 public int getCount() {
 return mAnimals.size();
 }


 @Override
 public Filter getFilter() {
 if (animalFilter == null)
 animalFilter = new AnimalFilter();

 return animalFilter;

 }

 private class AnimalFilter extends Filter {



 @Override
 protected FilterResults performFiltering(CharSequence constraint) {

 FilterResults results = new FilterResults();
 // We implement here the filter logic
 if (constraint == null || constraint.length() == 0) {
 // No filter implemented we return all the list
 results.values = animaly;
 results.count = animaly.size();


 }
 if (constraint!= null && constraint.toString().length() > 0) {
 List<animal> nAnimalList = new ArrayList<animal>();
 for (Animal p : animaly) {
 if (p.getAnimal().toUpperCase().contains(constraint.toString().toUpperCase())
 &&p.getAnimal().toUpperCase().startsWith(constraint.toString().toUpperCase()))


 nAnimalList.add(p);


 if (p.getAnimal().toUpperCase().contains(constraint.toString().toUpperCase())
 &&!p.getAnimal().toUpperCase().startsWith(constraint.toString().toUpperCase()))
 nAnimalList.remove(p);


 }

 results.values = nAnimalList;
 results.count = nAnimalList.size(); 
 }

 return results;
 }

 @SuppressWarnings("unchecked")
 @Override
 protected void publishResults(CharSequence constraint,
 FilterResults results) {

 // Now we have to inform the adapter about the new list filtered
 if (results.count == 0)
 notifyDataSetInvalidated();
 else {
 mAnimals = (List<animal>) results.values;
 notifyDataSetChanged();
 }

 }

 }


}
</animal></animal></animal></animal></animal></animal></animal>
3 ответа

Хотя я думаю, что ваша логика, заполняющая список, может быть отключена (т.е. Нет необходимости делать.remove() в списке, который начинается пустым), ваша ошибка может быть в publishResults:

if (results.count == 0)
 notifyDataSetInvalidated(); // <-- this isn't right
else 
{
 mAnimals = (List<animal>) results.values;
 notifyDataSetChanged();
}
</animal>

notifyDataSetInvalidated() скорее всего не то, что вы хотите сделать, чтобы удалить свой список, сделайте это вместо этого:

@Override
protected void publishResults(CharSequence constraint, FilterResults results) 
{
 // even if results.values is an empty List<animal>, you want to notify your adapter!
 mAnimals = (List<animal>) results.values;
 notifyDataSetChanged();
}
</animal></animal>


Попробуйте следующее:

if (constraint!= null && constraint.toString().length() > 0) {
 List<animal> nAnimalList = new ArrayList<animal>();
 for (Animal p : animaly) {
 if (p.getAnimal().toUpperCase().contains(constraint.toString().toUpperCase()))
 nAnimalList.add(p);
 }
 results.values = nAnimalList;
 results.count = nAnimalList.size(); 
}
</animal></animal>


if (p.getAnimal().toUpperCase().contains(constraint.toString().toUpperCase()) 
&& !p.getAnimal().toUpperCase().startsWith(constraint.toString().toUpperCase())) {
 nAnimalList.remove(p);
}

Давайте посмотрим, что оценивает каждое утверждение. Первая ложная, потому что "панда" не содержит "pansjdghas". Второй - истина, потому что "панда" не начинается с "pansdjlha", но вы отрицаете это, чтобы сделать ее правдой. Поскольку первый ложный, вы никогда не достигаете кода, который удаляет животное. Чтобы исправить это, просто отрицайте первое утверждение, так что это правда. Теперь ваш код должен выглядеть так:

if (!p.getAnimal().toUpperCase().contains(constraint.toString().toUpperCase()) 
&& !p.getAnimal().toUpperCase().startsWith(constraint.toString().toUpperCase())) {
 nAnimalList.remove(p);
}

licensed under cc by-sa 3.0 with attribution.