删除过滤器文本后,CustomArrayAdapter 不会刷新
CustomArrayAdapter doesn't refresh after filter text has been removed
大家好,我实现了自己的 ArrayAdapter,因为我在单个 ListView 项中有两个文本视图。
虽然过滤工作正常(它显示正确的项目),但当我删除我输入的用于过滤项目的文本时,ListView 不会进入其初始状态(它不会显示所有项目),而只是离开过滤列表不变。
这是我的过滤器实现:
private class NightFilter extends Filter {
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
items = (ArrayList<NightOut>) results.values;
clear();
int count = items.size();
for (int i = 0; i < count; i++) {
NightOut pkmn = (NightOut) items.get(i);
add(pkmn);
}
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults result = new FilterResults();
if (constraint == null || constraint.length() == 0) {
ArrayList<NightOut> list = new ArrayList<NightOut>(nightsOut);
result.values = list;
result.count = list.size();
} else {
final ArrayList<NightOut> list = new ArrayList<NightOut>(nightsOut);
final ArrayList<NightOut> nlist = new ArrayList<NightOut>();
int count = list.size();
for (int i = 0; i < count; i++) {
final NightOut nightOut = list.get(i);
final String value = nightOut.getAddress().toLowerCase();
if (value.contains(constraint.toString().toLowerCase())) {
nlist.add(nightOut);
}
}
result.values = nlist;
result.count = nlist.size();
}
return result;
}
}
nightsOut 和 items 都包含我要过滤的对象(我在构造函数中分配它们)。如果有任何帮助,我的自定义适配器 class 扩展了 ArrayAdapter。
编辑:
添加了构造函数和文本过滤代码
public CustomArrayAdapter(Activity context, ArrayList<NightOut> nightsOut) {
super(context, R.layout.list_item, nightsOut);
this.context = context;
this.nightsOut = nightsOut;
this.items = nightsOut;
}
搜索方式
inputSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
ViewPlacesActivity.this.adapter.getFilter().filter(cs);
}
知道我错过了什么吗?
干杯凯尔
您使用 nightsOut
作为 ArrayAdapter
的源列表以及过滤器的源列表的方式是导致问题的原因。
在 publishResults()
方法中,您调用了 clear()
,它从 nightsOut
列表中删除了 ArrayAdapter
内的所有元素,因为这是它引用的列表。然后您只读取过滤后的数据。
然后下次调用 performFiltering()
时,您将再次使用 nightsOut
作为源列表,其中仅包含已过滤的项目。
您要做的是保留对原始项目的引用。您实际上并不需要 items
当前使用的方式,因此我将其重命名为 originalItems
并执行以下操作:
public CustomArrayAdapter(Activity context, ArrayList<NightOut> nightsOut) {
super(context, R.layout.list_item, nightsOut);
this.context = context;
this.nightsOut = nightsOut;
originalItems = new ArrayList<>(nightsOut); // create a copy of nightsOut.
}
然后是过滤器
private class NightFilter extends Filter {
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
ArrayList<NightOut> tempList = (ArrayList<NightOut>) results.values;
clear();
addAll(tempList);
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults result = new FilterResults();
if (constraint == null || constraint.length() == 0) {
result.values = originalItems;
result.count = originalItems.size();
} else {
final ArrayList<NightOut> nlist = new ArrayList<NightOut>();
String lowerConstraint = constraint.toString().toLowerCase();
// loop through originalItems which always contains all items
for(NightOut nightOut : originalItems) {
final String value = nightOut.getAddress().toLowerCase();
if (value.contains(lowerConstraint)) {
nlist.add(nightOut);
}
}
result.values = nlist;
result.count = nlist.size();
}
return result;
}
}
大家好,我实现了自己的 ArrayAdapter,因为我在单个 ListView 项中有两个文本视图。 虽然过滤工作正常(它显示正确的项目),但当我删除我输入的用于过滤项目的文本时,ListView 不会进入其初始状态(它不会显示所有项目),而只是离开过滤列表不变。 这是我的过滤器实现:
private class NightFilter extends Filter {
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
items = (ArrayList<NightOut>) results.values;
clear();
int count = items.size();
for (int i = 0; i < count; i++) {
NightOut pkmn = (NightOut) items.get(i);
add(pkmn);
}
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults result = new FilterResults();
if (constraint == null || constraint.length() == 0) {
ArrayList<NightOut> list = new ArrayList<NightOut>(nightsOut);
result.values = list;
result.count = list.size();
} else {
final ArrayList<NightOut> list = new ArrayList<NightOut>(nightsOut);
final ArrayList<NightOut> nlist = new ArrayList<NightOut>();
int count = list.size();
for (int i = 0; i < count; i++) {
final NightOut nightOut = list.get(i);
final String value = nightOut.getAddress().toLowerCase();
if (value.contains(constraint.toString().toLowerCase())) {
nlist.add(nightOut);
}
}
result.values = nlist;
result.count = nlist.size();
}
return result;
}
}
nightsOut 和 items 都包含我要过滤的对象(我在构造函数中分配它们)。如果有任何帮助,我的自定义适配器 class 扩展了 ArrayAdapter。
编辑:
添加了构造函数和文本过滤代码
public CustomArrayAdapter(Activity context, ArrayList<NightOut> nightsOut) {
super(context, R.layout.list_item, nightsOut);
this.context = context;
this.nightsOut = nightsOut;
this.items = nightsOut;
}
搜索方式
inputSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
ViewPlacesActivity.this.adapter.getFilter().filter(cs);
}
知道我错过了什么吗?
干杯凯尔
您使用 nightsOut
作为 ArrayAdapter
的源列表以及过滤器的源列表的方式是导致问题的原因。
在 publishResults()
方法中,您调用了 clear()
,它从 nightsOut
列表中删除了 ArrayAdapter
内的所有元素,因为这是它引用的列表。然后您只读取过滤后的数据。
然后下次调用 performFiltering()
时,您将再次使用 nightsOut
作为源列表,其中仅包含已过滤的项目。
您要做的是保留对原始项目的引用。您实际上并不需要 items
当前使用的方式,因此我将其重命名为 originalItems
并执行以下操作:
public CustomArrayAdapter(Activity context, ArrayList<NightOut> nightsOut) {
super(context, R.layout.list_item, nightsOut);
this.context = context;
this.nightsOut = nightsOut;
originalItems = new ArrayList<>(nightsOut); // create a copy of nightsOut.
}
然后是过滤器
private class NightFilter extends Filter {
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
ArrayList<NightOut> tempList = (ArrayList<NightOut>) results.values;
clear();
addAll(tempList);
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults result = new FilterResults();
if (constraint == null || constraint.length() == 0) {
result.values = originalItems;
result.count = originalItems.size();
} else {
final ArrayList<NightOut> nlist = new ArrayList<NightOut>();
String lowerConstraint = constraint.toString().toLowerCase();
// loop through originalItems which always contains all items
for(NightOut nightOut : originalItems) {
final String value = nightOut.getAddress().toLowerCase();
if (value.contains(lowerConstraint)) {
nlist.add(nightOut);
}
}
result.values = nlist;
result.count = nlist.size();
}
return result;
}
}