列表视图中的过滤器不是从完整列表中过滤,而是从已过滤的列表中过滤
Filter in listview did not filter from the full list, but from already filtered list
我有一个带过滤器的列表视图。当我在用作过滤器的 edittext 中输入一些单词时,例如 "david",它运行良好,列表中的项目被过滤,它将显示包含 "david" 的所有项目。但是当我删除一些单词时,例如"dav",列表仍然被过滤,但是它是从上次被"david"过滤的过滤出来的。
假设我有 40 件商品,经过 "david" 筛选后,结果变成了 24 件。然后我用 "dav" 再次过滤它,它从“24 项”过滤,而不是“40 项”过滤。
这是我的自定义适配器:
public class WRegistrantListAdapter extends ArrayAdapter<Registrant> {
private Context mContext;
private int mResource;
private List<Registrant> mOriginalList;
private List<Registrant> mFilteredList;
public WRegistrantListAdapter(Context context, int resource, ArrayList<Registrant> oobjects, int workshopItemId) {
super(context, resource, oobjects);
mContext = context;
mResource = resource;
mFilteredList = oobjects;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
//contains code for displaying item.
}
@NonNull
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
FilterResults result = new FilterResults();
String constraint = charSequence.toString().toLowerCase();
if (mOriginalList == null) {
mOriginalList = mFilteredList;
Toast.makeText(mContext, String.valueOf(mOriginalList.size()), Toast.LENGTH_SHORT).show();
}
if (constraint == null || constraint.isEmpty() || constraint.equals("")) {
result.values = mOriginalList;
result.count = mOriginalList.size();
} else {
List<Registrant> list = new ArrayList<>();
int max = mOriginalList.size();
for (int cont = 0; cont < max; cont++) {
Registrant item = mOriginalList.get(cont);
boolean contains =
item.getRegistrantName().toLowerCase().contains(constraint) ||
item.getRegistrantNumber().toLowerCase().contains(constraint);
if (contains) {
list.add(mOriginalList.get(cont));
}
}
result.values = list;
result.count = list.size();
}
return result;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
clear();
addAll((ArrayList<Registrant>) results.values);
notifyDataSetChanged();
}
};
}
}
过滤的哪一部分是错误的?任何帮助将非常感激。希望我的解释不会造成混淆,因为英语不是我的母语。
您应该在适配器中保留两个单独的列表,例如,
private List<Registrant> mOriginalList = new ArrayList();
private List<Registrant> mFilteredList = new ArrayList();
public WRegistrantListAdapter(Context context, int resource, ArrayList<Registrant> oobjects, int workshopItemId) {
super(context, resource, oobjects);
mContext = context;
mResource = resource;
mFilteredList.addAll(oobjects);
mOriginalList.addAll(oobjects);
}
最初,它们应该具有相同的值,您将使用 filteredList 来显示您的数据。稍后在过滤器中,您应该像
一样发布您的数据
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
filteredList.clear();
filteredList.addAll((ArrayList<Registrant>) results.values);
notifyDataSetChanged();
}
可以在 Filter ListView with arrayadapter
中找到完整的示例
您需要两个不同的列表进行过滤,因此尝试将 mOriginalList = mFilteredList;
更改为 mOriginalList = new ArrayList<>(mFilteredList);
可能会解决问题。
解释:
mOriginalList = mFilteredList;
是具有两个不同名称的相同列表。它在模块化程序中很有用,就像适配器构造函数中的 mFilteredList = oobjects;
。
mOriginalList = new ArrayList<>(mFilteredList);
是对mFilteredList做一个shallow拷贝,存为mOriginalList,所以列表不一样
浅层和深层复制:
示例:如果您的自定义 class、Registrant 包含 public 字段(列表、地图或自定义对象等,则需要 new 用于创建)名为 sample
。在浅拷贝下,mOriginalList = new ArrayList<>(mFilteredList);
、mOriginalList.get(i) 是 mFilteredList.get(i) 的副本,它们是 2 个不同的 Registrant 对象。但是 mOriginalList.get(i).sample 和 mFilteredList.get(i).sample 是同一个对象。
如果需要mOriginalList.get(i).sample和mFilteredList.get(i).sample是不同的对象,那么就叫深拷贝。制作深拷贝没有现成的方法,你必须根据你的习惯制作你自己的方法class。但是到现在为止,我从来没有一个案例需要深拷贝。
希望对您有所帮助!
我有一个带过滤器的列表视图。当我在用作过滤器的 edittext 中输入一些单词时,例如 "david",它运行良好,列表中的项目被过滤,它将显示包含 "david" 的所有项目。但是当我删除一些单词时,例如"dav",列表仍然被过滤,但是它是从上次被"david"过滤的过滤出来的。
假设我有 40 件商品,经过 "david" 筛选后,结果变成了 24 件。然后我用 "dav" 再次过滤它,它从“24 项”过滤,而不是“40 项”过滤。
这是我的自定义适配器:
public class WRegistrantListAdapter extends ArrayAdapter<Registrant> {
private Context mContext;
private int mResource;
private List<Registrant> mOriginalList;
private List<Registrant> mFilteredList;
public WRegistrantListAdapter(Context context, int resource, ArrayList<Registrant> oobjects, int workshopItemId) {
super(context, resource, oobjects);
mContext = context;
mResource = resource;
mFilteredList = oobjects;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
//contains code for displaying item.
}
@NonNull
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
FilterResults result = new FilterResults();
String constraint = charSequence.toString().toLowerCase();
if (mOriginalList == null) {
mOriginalList = mFilteredList;
Toast.makeText(mContext, String.valueOf(mOriginalList.size()), Toast.LENGTH_SHORT).show();
}
if (constraint == null || constraint.isEmpty() || constraint.equals("")) {
result.values = mOriginalList;
result.count = mOriginalList.size();
} else {
List<Registrant> list = new ArrayList<>();
int max = mOriginalList.size();
for (int cont = 0; cont < max; cont++) {
Registrant item = mOriginalList.get(cont);
boolean contains =
item.getRegistrantName().toLowerCase().contains(constraint) ||
item.getRegistrantNumber().toLowerCase().contains(constraint);
if (contains) {
list.add(mOriginalList.get(cont));
}
}
result.values = list;
result.count = list.size();
}
return result;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
clear();
addAll((ArrayList<Registrant>) results.values);
notifyDataSetChanged();
}
};
}
}
过滤的哪一部分是错误的?任何帮助将非常感激。希望我的解释不会造成混淆,因为英语不是我的母语。
您应该在适配器中保留两个单独的列表,例如,
private List<Registrant> mOriginalList = new ArrayList();
private List<Registrant> mFilteredList = new ArrayList();
public WRegistrantListAdapter(Context context, int resource, ArrayList<Registrant> oobjects, int workshopItemId) {
super(context, resource, oobjects);
mContext = context;
mResource = resource;
mFilteredList.addAll(oobjects);
mOriginalList.addAll(oobjects);
}
最初,它们应该具有相同的值,您将使用 filteredList 来显示您的数据。稍后在过滤器中,您应该像
一样发布您的数据@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
filteredList.clear();
filteredList.addAll((ArrayList<Registrant>) results.values);
notifyDataSetChanged();
}
可以在 Filter ListView with arrayadapter
中找到完整的示例您需要两个不同的列表进行过滤,因此尝试将 mOriginalList = mFilteredList;
更改为 mOriginalList = new ArrayList<>(mFilteredList);
可能会解决问题。
解释:
mOriginalList = mFilteredList;
是具有两个不同名称的相同列表。它在模块化程序中很有用,就像适配器构造函数中的 mFilteredList = oobjects;
。
mOriginalList = new ArrayList<>(mFilteredList);
是对mFilteredList做一个shallow拷贝,存为mOriginalList,所以列表不一样
浅层和深层复制:
示例:如果您的自定义 class、Registrant 包含 public 字段(列表、地图或自定义对象等,则需要 new 用于创建)名为 sample
。在浅拷贝下,mOriginalList = new ArrayList<>(mFilteredList);
、mOriginalList.get(i) 是 mFilteredList.get(i) 的副本,它们是 2 个不同的 Registrant 对象。但是 mOriginalList.get(i).sample 和 mFilteredList.get(i).sample 是同一个对象。
如果需要mOriginalList.get(i).sample和mFilteredList.get(i).sample是不同的对象,那么就叫深拷贝。制作深拷贝没有现成的方法,你必须根据你的习惯制作你自己的方法class。但是到现在为止,我从来没有一个案例需要深拷贝。
希望对您有所帮助!