清除搜索后列表视图未返回到原始状态
List view not returning to original state after clearing search
每当我从搜索视图中取消搜索时,我都试图让我的列表再次显示我的所有项目,但由于某些奇怪的原因,该列表只显示上一次搜索的结果。有谁知道我的代码有什么问题以及如何解决这个问题?我相信过滤器相关代码有问题,但我不知道它是什么。
FilterListFragment.java
public class ItemListAdapter extends BaseAdapter implements Filterable {
private List<Item> mData;
private List<Item> mFilteredData;
private LayoutInflater mInflater;
private ItemFilter mFilter;
public ItemListAdapter (List<Item> data, Context context) {
mData = data;
mFilteredData = data;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return mFilteredData.size();
}
@Override
public String getItem(int position) {
return mFilteredData.get(position).getItem();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_row, parent, false);
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.item_title);
holder.description = (TextView) convertView.findViewById(R.id.item_description);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.title.setText(mData.get(position).getItem());
holder.description.setText(mData.get(position).getItemDescription());
return convertView;
}
@Override
public Filter getFilter() {
if (mFilter == null) {
mFilter = new ItemFilter();
}
return mFilter;
}
/**
* View holder
*/
static class ViewHolder {
private TextView title;
private TextView description;
}
/**
* Filter for filtering list items
*/
private class ItemFilter extends Filter {
/**
* Invoked on a background thread. This is where all the filter logic should go
* @param constraint the constraint to filter on
* @return the resulting list after applying the constraint
*/
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (TextUtils.isEmpty(constraint)) {
results.count = mData.size();
results.values = mData;
} else {
//Create a new list to filter on
List<Item> resultList = new ArrayList<Item>();
for (Item str : mData) {
if (str.getItem().toLowerCase().contains(constraint.toString().toLowerCase())) {
resultList.add(str);
}
}
results.count = resultList.size();
results.values = resultList;
}
return results;
}
/**
* Runs on ui thread
* @param constraint the constraint used for the result
* @param results the results to display
*/
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results.count == 0) {
notifyDataSetInvalidated();
} else {
mFilteredData = (ArrayList<Item>)results.values;
notifyDataSetChanged();
}
}
}
}
列表处于正常状态
处于筛选状态的列表
向 onQueryTextChange() 添加一条日志语句,以便您可以查看过滤器字符串的变化情况。请注意,当搜索视图关闭时,SearchView 不会使用空字符串调用 onQueryTextChange()。您需要决定何时清除搜索字符串,也许可以为此添加一个控件,然后自己进行清除。
您正在对原始数据而不是过滤后的数据进行操作。您应该保留对原始数据的引用,并将过滤后的数据用于所有其他目的。以便清除搜索时显示原始数据。
将mData
的所有用法替换为mFilteredData
,如下所示,仅使用原始数据生成过滤后的数据:
private List<String> mData;
private List<String> mFilteredData;
private LayoutInflater mInflater;
private ItemFilter mFilter;
public ItemListAdapter (List<String> data, Context context) {
mData = data;
mFilteredData = data;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return mFilteredData.size();
}
@Override
public String getItem(int position) {
return mFilteredData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
String strItem = mFilteredData.get(position);
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_row, parent, false);
holder = new ViewHolder();
holder.mTvItem = (TextView) convertView.findViewById(R.id.tv_item);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.mTvItem.setText(strItem);
return convertView;
}
@Override
public Filter getFilter() {
if (mFilter == null) {
mFilter = new ItemFilter();
}
return mFilter;
}
/**
* View holder
*/
static class ViewHolder {
private TextView mTvItem;
}
/**
* Filter for filtering list items
*/
private class ItemFilter extends Filter {
/**
* Invoked on a background thread. This is where all the filter logic should go
* @param constraint the constraint to filter on
* @return the resulting list after applying the constraint
*/
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (TextUtils.isEmpty(constraint)) {
results.count = mData.size();
results.values = mData;
} else {
//Create a new list to filter on
List<String> resultList = new ArrayList<>();
for (String str : mData) {
if (str.toLowerCase().contains(constraint.toString().toLowerCase())) {
resultList.add(str);
}
}
results.count = resultList.size();
results.values = resultList;
}
return results;
}
/**
* Runs on ui thread
* @param constraint the constraint used for the result
* @param results the results to display
*/
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results.count == 0) {
notifyDataSetInvalidated();
} else {
mFilteredData = (ArrayList<String>)results.values;
notifyDataSetChanged();
}
}
}
每当我从搜索视图中取消搜索时,我都试图让我的列表再次显示我的所有项目,但由于某些奇怪的原因,该列表只显示上一次搜索的结果。有谁知道我的代码有什么问题以及如何解决这个问题?我相信过滤器相关代码有问题,但我不知道它是什么。
FilterListFragment.java
public class ItemListAdapter extends BaseAdapter implements Filterable {
private List<Item> mData;
private List<Item> mFilteredData;
private LayoutInflater mInflater;
private ItemFilter mFilter;
public ItemListAdapter (List<Item> data, Context context) {
mData = data;
mFilteredData = data;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return mFilteredData.size();
}
@Override
public String getItem(int position) {
return mFilteredData.get(position).getItem();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_row, parent, false);
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.item_title);
holder.description = (TextView) convertView.findViewById(R.id.item_description);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.title.setText(mData.get(position).getItem());
holder.description.setText(mData.get(position).getItemDescription());
return convertView;
}
@Override
public Filter getFilter() {
if (mFilter == null) {
mFilter = new ItemFilter();
}
return mFilter;
}
/**
* View holder
*/
static class ViewHolder {
private TextView title;
private TextView description;
}
/**
* Filter for filtering list items
*/
private class ItemFilter extends Filter {
/**
* Invoked on a background thread. This is where all the filter logic should go
* @param constraint the constraint to filter on
* @return the resulting list after applying the constraint
*/
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (TextUtils.isEmpty(constraint)) {
results.count = mData.size();
results.values = mData;
} else {
//Create a new list to filter on
List<Item> resultList = new ArrayList<Item>();
for (Item str : mData) {
if (str.getItem().toLowerCase().contains(constraint.toString().toLowerCase())) {
resultList.add(str);
}
}
results.count = resultList.size();
results.values = resultList;
}
return results;
}
/**
* Runs on ui thread
* @param constraint the constraint used for the result
* @param results the results to display
*/
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results.count == 0) {
notifyDataSetInvalidated();
} else {
mFilteredData = (ArrayList<Item>)results.values;
notifyDataSetChanged();
}
}
}
}
列表处于正常状态
处于筛选状态的列表
向 onQueryTextChange() 添加一条日志语句,以便您可以查看过滤器字符串的变化情况。请注意,当搜索视图关闭时,SearchView 不会使用空字符串调用 onQueryTextChange()。您需要决定何时清除搜索字符串,也许可以为此添加一个控件,然后自己进行清除。
您正在对原始数据而不是过滤后的数据进行操作。您应该保留对原始数据的引用,并将过滤后的数据用于所有其他目的。以便清除搜索时显示原始数据。
将mData
的所有用法替换为mFilteredData
,如下所示,仅使用原始数据生成过滤后的数据:
private List<String> mData;
private List<String> mFilteredData;
private LayoutInflater mInflater;
private ItemFilter mFilter;
public ItemListAdapter (List<String> data, Context context) {
mData = data;
mFilteredData = data;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return mFilteredData.size();
}
@Override
public String getItem(int position) {
return mFilteredData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
String strItem = mFilteredData.get(position);
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_row, parent, false);
holder = new ViewHolder();
holder.mTvItem = (TextView) convertView.findViewById(R.id.tv_item);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.mTvItem.setText(strItem);
return convertView;
}
@Override
public Filter getFilter() {
if (mFilter == null) {
mFilter = new ItemFilter();
}
return mFilter;
}
/**
* View holder
*/
static class ViewHolder {
private TextView mTvItem;
}
/**
* Filter for filtering list items
*/
private class ItemFilter extends Filter {
/**
* Invoked on a background thread. This is where all the filter logic should go
* @param constraint the constraint to filter on
* @return the resulting list after applying the constraint
*/
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (TextUtils.isEmpty(constraint)) {
results.count = mData.size();
results.values = mData;
} else {
//Create a new list to filter on
List<String> resultList = new ArrayList<>();
for (String str : mData) {
if (str.toLowerCase().contains(constraint.toString().toLowerCase())) {
resultList.add(str);
}
}
results.count = resultList.size();
results.values = resultList;
}
return results;
}
/**
* Runs on ui thread
* @param constraint the constraint used for the result
* @param results the results to display
*/
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results.count == 0) {
notifyDataSetInvalidated();
} else {
mFilteredData = (ArrayList<String>)results.values;
notifyDataSetChanged();
}
}
}