我的自定义搜索视图无法正常工作,当搜索输入为空时不显示原始列表
My custom search view is not working correctly, not showing original list when search input is null
我正在尝试在我的 activity 中实现自定义可搜索微调器,但代码中有问题,我找不到它。查看下面的屏幕截图以了解我的问题。
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;
}
}
您保留了一个列表 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();
}
}
}
我正在尝试在我的 activity 中实现自定义可搜索微调器,但代码中有问题,我找不到它。查看下面的屏幕截图以了解我的问题。
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;
}
}
您保留了一个列表 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();
}
}
}