【问题标题】:ListView Search Filter leaves unwelcome dataListView 搜索过滤器留下不受欢迎的数据
【发布时间】:2014-01-25 18:03:21
【问题描述】:

我的 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's 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();
                 }

         }

 }


}

【问题讨论】:

  • 离题但我喜欢可爱的小猫图片:3
  • 哈哈哈哈哈。不错的选择吧?

标签: java android listview search filter


【解决方案1】:

虽然我认为您填充列表的逻辑可能已关闭(即无需对以空开头的列表执行 .remove()),但您的错误可能在 publishResults 中:

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

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();
}

【讨论】:

  • 感谢您的回答 CSmith。当没有结果适合时,我如何实现列表为空? (不以某些字母开头或不包含某些序列)
  • 如果 mAnimals 引用一个空的 List,假设您的列表由 mAnimals 填充,上述建议应该有效。
  • 想了几分钟你的答案,我终于明白了。这是真的,但我认为,如果我设置函数包含和 staetsWith,文本(例如“pandasnifsdni ...”)也会出现在那里,因为它至少包含序列的一部分。我是真的吗?
  • @mansoulx 的过滤逻辑正确(您只需要检查 contains() 以查看结果中是否存在字符串),将他的解决方案与我的解决方案结合起来。
【解决方案2】:

试试这个:

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();  
}

【讨论】:

  • 感谢您的回答,但没有奏效。尽管如此,当我输入不同的字母时,其余字母仍然在同一个地方。
  • 我做了一些改进,@CSmith 向我提出了建议,并将其与您的建议结合起来,终于奏效了。非常感谢!
【解决方案3】:
if (p.getAnimal().toUpperCase().contains(constraint.toString().toUpperCase()) 
&& !p.getAnimal().toUpperCase().startsWith(constraint.toString().toUpperCase())) {
    nAnimalList.remove(p);
}

让我们看看每个语句的计算结果。第一个是假的,因为“panda”不包含“pansjdghas”。第二个是真的,因为“panda”不是以“pansdjlha”开头的,但是你否定它来使它成为真的。因为第一个是假的,所以你永远无法找到删除动物的代码。要解决这个问题,只需简单地否定第一个语句,使其为真。您的代码现在应该如下所示:

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

【讨论】:

  • 我不太明白为什么必须移除动物。一开始就不应该添加它,对吧?
  • 嗨,Nathan,感谢您的回答,但它没有用。 Ascorbin:我想删除/隐藏所有对象,如果没有任何内容以字符开头并包含字符序列,并显示没有找到任何内容的 Toast。
猜你喜欢
  • 2018-09-24
  • 1970-01-01
  • 2013-02-10
  • 1970-01-01
  • 2015-10-04
  • 2021-02-20
  • 2013-08-04
  • 2022-01-14
  • 2018-11-07
相关资源
最近更新 更多