自定义 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_original
和 images
,所以我猜你的 'original words' 在过滤后也关闭了。
例如过滤后 words
中有 3 个元素(过滤后的项目),但其他 2 个数组列表仍包含所有项目,导致您描述的问题。
将过滤器应用于整个数据集(words
、words_original
和 images
),它应该可以工作。
问题是您只过滤 words
列表而不过滤 images
列表。因此,一旦从单词列表中过滤掉一个单词,单词和图像列表就不再平行,这会导致显示错误的图像。
您可以通过创建 images_original
列表并删除 images
列表相同索引处的元素来解决此问题。换句话说,如果你删除了一个词,你还需要在相同的位置删除相应的图像。
但是,更好的方法是将这两个值存储在一个对象中,然后基于新对象创建一个列表。因此,创建一个包含 String word
和 int image
的新 class,并保留一个由新 class 组成的列表。这将为您简化事情,然后您也只需过滤一个列表而不是两个单独的列表。
我正在尝试制作一个自定义适配器来用字符串及其相应的图像填充 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_original
和 images
,所以我猜你的 'original words' 在过滤后也关闭了。
例如过滤后 words
中有 3 个元素(过滤后的项目),但其他 2 个数组列表仍包含所有项目,导致您描述的问题。
将过滤器应用于整个数据集(words
、words_original
和 images
),它应该可以工作。
问题是您只过滤 words
列表而不过滤 images
列表。因此,一旦从单词列表中过滤掉一个单词,单词和图像列表就不再平行,这会导致显示错误的图像。
您可以通过创建 images_original
列表并删除 images
列表相同索引处的元素来解决此问题。换句话说,如果你删除了一个词,你还需要在相同的位置删除相应的图像。
但是,更好的方法是将这两个值存储在一个对象中,然后基于新对象创建一个列表。因此,创建一个包含 String word
和 int image
的新 class,并保留一个由新 class 组成的列表。这将为您简化事情,然后您也只需过滤一个列表而不是两个单独的列表。