我的自定义搜索视图无法正常工作,当搜索输入为空时不显示原始列表
Posted
技术标签:
【中文标题】我的自定义搜索视图无法正常工作,当搜索输入为空时不显示原始列表【英文标题】:My custom search view is not working correctly, not showing original list when search input is null 【发布时间】:2021-06-02 19:32:47 【问题描述】:我正在尝试在我的活动中实现自定义可搜索微调器,但代码中有问题,我找不到它。查看下面的屏幕截图以了解我的问题。
snap1 这是包含三个项目的原始列表视图,尚未添加搜索过滤器
snap2 这是搜索过滤器后的列表视图
snap3 这是删除搜索后的列表视图。
正如您在第三个屏幕截图中看到的那样,在清除搜索过滤器后,列表视图没有显示所有三个项目。你能看出我在代码中犯了什么错误吗?
ListAdapter.java
public class ListAdapter extends ArrayAdapter<SpinnerItem>
private List<SpinnerItem> items;
private Context context;
private Filter filter;
public ListAdapter(@NonNull Context context, int resource, List<SpinnerItem> items)
super(context, resource);
this.context = context;
this.items = items;
this.filter = new CustomItemsFilter();
@Nullable
@Override
public SpinnerItem getItem(int position)
return items.get(position);
@Override
public int getCount()
return items.size();
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent)
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rootView = inflater.inflate(R.layout.list_item,parent,false);
TextView textView = rootView.findViewById(R.id.itemTitle);
TextView textView1 = rootView.findViewById(R.id.itemSubTitle);
TextView textView2 = rootView.findViewById(R.id.itemSign);
textView.setText(items.get(position).getTitle());
textView1.setText(items.get(position).getSubTitle());
textView2.setText(items.get(position).getSign());
return rootView;
@NonNull
@Override
public Filter getFilter()
if(filter == null)
filter = new CustomItemsFilter();
return filter;
private class CustomItemsFilter extends Filter
@Override
protected FilterResults performFiltering(CharSequence constraint)
FilterResults filterResults = new FilterResults();
if(constraint != null && constraint.toString().length() > 0)
constraint = constraint.toString().toLowerCase();
List<SpinnerItem> allItems = new ArrayList<SpinnerItem>();
List<SpinnerItem> filterItems = new ArrayList<SpinnerItem>();
synchronized (this)
allItems.addAll(items);
for (int i = 0; i < allItems.size(); ++i)
SpinnerItem item = allItems.get(i);
if(item.getTitle().contains(constraint) || item.getSubTitle().contains(constraint) || item.getSign().contains(constraint))
filterItems.add(item);
filterResults.count = filterItems.size();
filterResults.values = filterItems;
else
synchronized (this)
filterResults.values = items;
filterResults.count = items.size();
return filterResults;
@Override
protected void publishResults(CharSequence constraint, FilterResults results)
if(results.count > 0)
items = (List<SpinnerItem>) results.values;
notifyDataSetChanged();
SpinnerDialog.java
public class SpinnerDiaglog implements SearchView.OnCloseListener, SearchView.OnQueryTextListener
private List<SpinnerItem> items;
private OnSpinnerItemClick onSpinnerItemClick;
private Activity context;
private SearchView searchView;
private DialogInterface.OnClickListener onClickListener;
private ListAdapter adapter;
private OnSearchTextChanged onSearchTextChanged;
private ListView listView;
private AlertDialog dialog;
public SpinnerDiaglog()
public SpinnerDiaglog(Activity context, List<SpinnerItem> items)
this.context = context;
this.items = items;
public void onCreateDialog()
View rootView = context.getLayoutInflater().inflate(R.layout.spinner_dialog,null);
//setData(rootView);
AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
alertDialog.setView(rootView);
alertDialog.setPositiveButton("CLOSE",onClickListener);
alertDialog.setTitle("Select Item");
SearchManager searchManager = (SearchManager) context.getSystemService(Context
.SEARCH_SERVICE);
searchView = rootView.findViewById(R.id.search);
searchView.setSearchableInfo(searchManager.getSearchableInfo(context.getComponentName()));
searchView.setOnQueryTextListener(this);
searchView.setOnCloseListener(this);
searchView.setIconifiedByDefault(false);
searchView.clearFocus();
listView = rootView.findViewById(R.id.listItems);
adapter = new ListAdapter(context,R.layout.list_item,items);
listView.setAdapter(adapter);
dialog = alertDialog.create();
dialog.show();
listView.setOnItemClickListener((parent, view, position, id) ->
onSpinnerItemClick.onClick(adapter.getItem(position),position);
dialog.dismiss();
);
public void setOnSpinnerItemClickListener(OnSpinnerItemClick onSpinnerItemClick)
this.onSpinnerItemClick = onSpinnerItemClick;
public void setOnSearchTextChangedListener(OnSearchTextChanged onSearchTextChanged)
this.onSearchTextChanged = onSearchTextChanged;
@Override
public boolean onQueryTextSubmit(String query)
searchView.clearFocus();
return false;
@Override
public boolean onQueryTextChange(String newText)
if(TextUtils.isEmpty(newText))
((ListAdapter) listView.getAdapter()).getFilter().filter(null);
else
((ListAdapter) listView.getAdapter()).getFilter().filter(newText);
if (null != onSearchTextChanged)
onSearchTextChanged.onSearchTextChanged(newText);
return true;
public interface OnSpinnerItemClick
void onClick(SpinnerItem item, int position);
public interface OnSearchTextChanged
void onSearchTextChanged(String strText);
@Override
public boolean onClose()
return false;
MainActivity.java
public class MainActivity2 extends AppCompatActivity
private SpinnerDiaglog spinnerDiaglog;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Button button = findViewById(R.id.show);
List<SpinnerItem> items = new ArrayList<>();
items.add(new SpinnerItemImp("Title","subTitle","sign"));
items.add(new SpinnerItemImp("aitle","subTitle","sign"));
items.add(new SpinnerItemImp("Tiastle","subTitle","sign"));
button.setOnClickListener(v ->
spinnerDiaglog = new SpinnerDiaglog(MainActivity2.this,items);
spinnerDiaglog.onCreateDialog();
);
SpinnerItemImp.java
public class SpinnerItemImp implements SpinnerItem
private String title;
private String subTitle;
private String sign;
public SpinnerItemImp(String title, String subTitle, String sign)
this.title = title;
this.subTitle = subTitle;
this.sign = sign;
@Override
public String getTitle()
return title;
@Override
public String getSubTitle()
return subTitle;
@Override
public String getSign()
return sign;
【问题讨论】:
【参考方案1】:您保留一个列表items
,当您第一次应用过滤器时,该列表会被修改。因此,在下一个过滤器中,您实际上是从过滤后的列表中过滤,而不是实际的列表。
您需要单独维护一个完整列表并在其上应用过滤器而不是在过滤后的列表上。下面是一个例子:
public class ListAdapter extends ArrayAdapter<SpinnerItem>
private List<SpinnerItem> items;
private List<SpinnerItem> allItems;
private Context context;
private Filter filter;
public ListAdapter(@NonNull Context context, int resource, List<SpinnerItem> items)
super(context, resource);
this.context = context;
this.items = items;
this.filter = new CustomItemsFilter();
allItems=new ArrayList<>(items);
@Override
public SpinnerItem getItem(int position)
return items.get(position);
@Override
public int getCount()
return items.size();
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent)
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rootView = inflater.inflate(R.layout.list_item,parent,false);
return rootView;
@NonNull
@Override
public Filter getFilter()
if(filter == null)
filter = new CustomItemsFilter();
return filter;
private class CustomItemsFilter extends Filter
@Override
protected FilterResults performFiltering(CharSequence constraint)
items.clear();
FilterResults filterResults = new FilterResults();
constraint = constraint.toString().trim().toLowerCase();
if (constraint.length() > 0)
for (int i = 0; i < allItems.size(); ++i)
SpinnerItem item = allItems.get(i);
if (item.getTitle().contains(constraint) || item.getSubTitle().contains(constraint) || item.getSign().contains(constraint))
items.add(item);
else
items.addAll(allItems);
filterResults.values = items;
filterResults.count = items.size();
return filterResults;
@Override
protected void publishResults(CharSequence constraint, FilterResults results)
items = (List<SpinnerItem>) results.values;
notifyDataSetChanged();
【讨论】:
以上是关于我的自定义搜索视图无法正常工作,当搜索输入为空时不显示原始列表的主要内容,如果未能解决你的问题,请参考以下文章