Android listview中的筛选器未从完整列表中筛选,而是从已筛选的列表中筛选
我有一个带过滤器的列表视图。当我在我用作过滤器的edittext中输入一些单词时,例如“david”,它工作正常,列表中的项目被过滤,它将显示包含“david”的所有项目。但当我删除一些单词时,例如“dav”,列表仍然被过滤,但它是从上一个被“dav”过滤的单词中过滤出来的 假设我有40个项目,通过“david”过滤,它变成24个项目。然后我用“dav”再次过滤,它是从“24项”过滤出来的,而不是从“40项”过滤出来的 这是我的自定义适配器:Android listview中的筛选器未从完整列表中筛选,而是从已筛选的列表中筛选,android,android-listview,android-filter,Android,Android Listview,Android Filter,我有一个带过滤器的列表视图。当我在我用作过滤器的edittext中输入一些单词时,例如“david”,它工作正常,列表中的项目被过滤,它将显示包含“david”的所有项目。但当我删除一些单词时,例如“dav”,列表仍然被过滤,但它是从上一个被“dav”过滤的单词中过滤出来的 假设我有40个项目,通过“david”过滤,它变成24个项目。然后我用“dav”再次过滤,它是从“24项”过滤出来的,而不是从“40项”过滤出来的 这是我的自定义适配器: public class WRegistrantLi
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();
}
};
}
}
公共类WRegistrantListAdapter扩展了ArrayAdapter{
私有上下文;
私人国际资源;
私人名单莫里金主义者;
私人名单;
公共WRegistrantListAdapter(上下文上下文、int资源、ArrayList对象、int workshopItemId){
超级(上下文、资源、对象);
mContext=上下文;
mResource=资源;
mFilteredList=oobjects;
}
@非空
@凌驾
公共视图getView(int位置,@Nullable视图convertView,@NonNull视图组父级){
//包含用于显示项目的代码。
}
@非空
@凌驾
公共过滤器getFilter(){
返回新筛选器(){
@凌驾
受保护过滤器结果执行过滤(CharSequence CharSequence){
FilterResults结果=新的FilterResults();
字符串约束=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();
}否则{
列表=新的ArrayList();
int max=mOriginalList.size();
对于(int cont=0;cont
过滤的哪一部分是错误的?任何帮助都将不胜感激。希望我的解释不会让人困惑,因为英语不是我的母语。您应该在适配器中保留两个单独的列表,例如
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);
}
private List mOriginalList=new ArrayList();
私有列表mFilteredList=newarraylist();
公共WRegistrantListAdapter(上下文上下文、int资源、ArrayList对象、int workshopItemId){
超级(上下文、资源、对象);
mContext=上下文;
mResource=资源;
mFilteredList.addAll(对象);
mOriginalList.addAll(对象);
}
最初,它们应该具有相同的值,您将使用filteredList显示数据。在过滤器的后面,您应该发布数据,如
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
filteredList.clear();
filteredList.addAll((ArrayList<Registrant>) results.values);
notifyDataSetChanged();
}
@覆盖
受保护的void publishResults(CharSequence约束、FilterResults结果){
filteredList.clear();
filteredList.addAll((ArrayList)results.values);
notifyDataSetChanged();
}
一个完整的例子是可以在中找到,您需要两个不同的列表进行筛选,因此请尝试更改mOriginalList=mFilteredListto
mOriginalList=newarraylist(mFilteredList)代码>可以解决此问题
说明:
mOriginalList=mFilteredList代码>是具有两个不同名称的相同列表。它在模块化程序中很有用,就像mFilteredList=oobjects代码>在适配器构造函数中
mOriginalList=newarraylist(mFilteredList)
是制作mFilteredList的浅层副本并将其存储为mOriginalList,因此列表不同
浅拷贝和深拷贝:
示例:如果您的自定义类,registent包含名为sample
的公共字段(列表、地图或自定义对象等,需要创建new)。在浅拷贝下,mOriginalList=newarraylist(mFilteredList)代码>,mOriginalList.get(i)是mFilteredList.get(i)的副本,它们是两个不同的注册者对象。但是mOriginalList.get(i).sample和mFilteredList.get(i).sample是同一个对象
如果需要将mOriginalList.get(i).sample和mFilteredList.get(i).sample作为不同的对象,则称为深度复制。没有现成的方法进行深度复制,您必须根据自定义类创建自己的方法。但到目前为止,我还没有一个案例需要深度复制
希望有帮助 我试过你的建议,但结果还是一样。mList的大小已更改,但我没有对其执行任何操作。我根据您提供的链接更新了代码库。我将mList更改为mOriginalList,以使其更易于理解。但仍然是一样的,mOriginalList的大小发生了变化,因为它不应该将相同的对象分配给两个列表。您可以在构造函数中执行此操作。我已经更新了我的答案,希望