自定义 ArrayAdapter 在过滤后显示错误的图像

Custom ArrayAdapter shows wrong image after being filtered

我正在尝试制作一个自定义适配器来用字符串及其相应的图像填充 ListView。问题是当进行过滤时,图像保持与未过滤时相同的顺序,而不是正确过滤和显示的字符串。我知道我在这里缺少将字符串和图像连接在一起的东西。现在有两个 ArrayList(具有匹配的索引)保留字符串及其图像。

import android.app.Activity;
import android.support.annotation.IdRes;
import android.support.annotation.LayoutRes;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;


public class WorterAdapter extends ArrayAdapter<String> implements Filterable
{
    private final Activity context;
    private ArrayList<String> words;
    private ArrayList<String> words_original;
    private ArrayList<Integer> images;
    private @LayoutRes int layout;
    private @IdRes int image_view;
    private @IdRes int text_view;
    private WortFilter filter;

    public WorterAdapter(Activity context,@LayoutRes int layout, @IdRes int text_view, @IdRes int image_view, ArrayList<String> words, ArrayList<Integer> images)
    {
        super(context, R.layout.wort_layout, words);
        this.context = context;
        this.words = words;
        this.words_original = new ArrayList<>(words);
        this.images = images;
        this.text_view = text_view;
        this.image_view = image_view;
        this.layout = layout;
    }
    @Override
    public View getView(int position, View view, ViewGroup parent)
    {
        LayoutInflater inflater = context.getLayoutInflater();
        View rowView= inflater.inflate(layout, null, true);
        TextView txtTitle = (TextView) rowView.findViewById(text_view);
        ImageView imageView = (ImageView) rowView.findViewById(image_view);
        txtTitle.setText(words.get(position));
        imageView.setImageResource(images.get(position));
        return rowView;
    }

    public Filter getFilter()
    {
        if (filter == null)
        {
            filter = new WortFilter();
        }
        return filter;
    }
    private class WortFilter extends Filter
    {
        @Override
        protected FilterResults performFiltering(CharSequence constraint)
        {
            FilterResults results = new FilterResults();;
            if(constraint == null || constraint.length() == 0)
            {
                words = new ArrayList<>(words_original);
                results.values = words;
                results.count = words.size();
            }
            else
            {
                words = new ArrayList<>(words_original);
                ArrayList<String> newValues = new ArrayList<>();
                for (String i : words)
                {
                    if (i.toUpperCase().contains(constraint.toString().toUpperCase()))
                        newValues.add(i);
                }
                results.values = newValues;
                results.count = newValues.size();
            }
            // TODO Auto-generated method stub
            return results;
        }
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results)
        {
            if (results.count == 0)
            {
                notifyDataSetInvalidated();
                clear();
            }
            else
            {
                @SuppressWarnings("unchecked")
                ArrayList<String> lst = (ArrayList<String>)results.values;
                words = new ArrayList<>(lst);
                clear();
                for (String item : words)
                {
                    add(item);
                }
                notifyDataSetChanged();
            }
        }
    }
}

我知道这个问题已经被问过好几次了,但我找不到适合我的其他解决方案。

你只是在过滤 words 而不是 words_originalimages,所以我猜你的 'original words' 在过滤后也关闭了。

例如过滤后 words 中有 3 个元素(过滤后的项目),但其他 2 个数组列表仍包含所有项目,导致您描述的问题。

将过滤器应用于整个数据集(wordswords_originalimages),它应该可以工作。

问题是您只过滤 words 列表而不过滤 images 列表。因此,一旦从单词列表中过滤掉一个单词,单词和图像列表就不再平行,这会导致显示错误的图像。

您可以通过创建 images_original 列表并删除 images 列表相同索引处的元素来解决此问题。换句话说,如果你删除了一个词,你还需要在相同的位置删除相应的图像。

但是,更好的方法是将这两个值存储在一个对象中,然后基于新对象创建一个列表。因此,创建一个包含 String wordint image 的新 class,并保留一个由新 class 组成的列表。这将为您简化事情,然后您也只需过滤一个列表而不是两个单独的列表。