无法通过 ListView 搜索,返回零结果
Posted
技术标签:
【中文标题】无法通过 ListView 搜索,返回零结果【英文标题】:Cannot search through the ListView, returns zero results 【发布时间】:2019-09-20 21:15:51 【问题描述】:我正在使用带有自定义适配器的 ListView,并且我有一个 EditText 用于搜索列表。 当我在 EditText 中键入任何内容时,它会用 ListView 清空。 注意:我在片段中的对话框中显示 ListView
我也添加了 TextChangedListener。 不知道我哪里出错了。 请提出建议。
CompanyAdapter companyAdapter;
private void showCompaniesDialog(List<Company> companies)
if(companies != null)
final Dialog dialog = new Dialog(getContext());
// dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setCancelable(false);
dialog.setContentView(R.layout.dialog_company_listview);
Button btndialog = (Button) dialog.findViewById(R.id.btndialog);
btndialog.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
dialog.dismiss();
);
ListView listView = (ListView) dialog.findViewById(R.id.listview);
companyAdapter = new CompanyAdapter(getActivity(), 0, companies);
listView.setAdapter(companyAdapter);
//HERE I SET THE TEXT FILTER ENABLED
listView.setTextFilterEnabled(true);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
//textView.setText("You have clicked : " + companies[position]);
dialog.dismiss();
);
//HERE I ADD CHANGED LISTENER
EditText etSearch = (EditText) dialog.findViewById(R.id.etSearch);
etSearch.addTextChangedListener(new TextWatcher()
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2)
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2)
companyAdapter.getFilter().filter(charSequence);
@Override
public void afterTextChanged(Editable editable)
//companyAdapter.getFilter().filter(editable);
);
dialog.show();
公司适配器
public class CompanyAdapter extends ArrayAdapter<Company>
private Activity activity;
private LayoutInflater inflater = null;
public CompanyAdapter (Activity activity, int textViewResourceId, List<Company> lCompany)
super(activity, textViewResourceId, lCompany);
try
this.activity = activity;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
catch (Exception e)
e.printStackTrace();
public Company getItem (Company position)
return position;
public long getItemId(int position)
return position;
public class ViewHolder
public TextView display_name;
@Override
public View getView(int position, View convertView, ViewGroup parent)
View vi = convertView;
final ViewHolder holder;
try
if (convertView == null)
vi = inflater.inflate(R.layout.company_list_item, null);
holder = new ViewHolder();
holder.display_name = (TextView) vi.findViewById(R.id.tvCompanyName);
vi.setTag(holder);
else
holder = (ViewHolder) vi.getTag();
holder.display_name.setText(getItem(position).getName());
catch (Exception e)
e.printStackTrace();
return vi;
名称字段的公司类
@SerializedName("name")
private String name;
public String getName()
return name;
public void setName(String name)
this.name = name;
【问题讨论】:
我没有看到你已经实现了过滤器。它不会神奇地理解你究竟想如何过滤它 @VladyslavMatviienko As Ganesh 建议我已经实现了 ItemFilter,我可以看到传递给 publishResults 方法的结果,但是 notifyDataSetChanged 不起作用,List 没有更新为新结果。关于我可能遗漏的任何建议 【参考方案1】:适配器必须implements Filterable
,检查此示例
public class SearchableAdapter extends BaseAdapter implements Filterable
private List<String>originalData = null;
private List<String>filteredData = null;
private LayoutInflater mInflater;
private ItemFilter mFilter = new ItemFilter();
public SearchableAdapter(Context context, List<String> data)
this.filteredData = data ;
this.originalData = data ;
mInflater = LayoutInflater.from(context);
public int getCount()
return filteredData.size();
public Object getItem(int position)
return filteredData.get(position);
public long getItemId(int position)
return position;
public View getView(int position, View convertView, ViewGroup parent)
// A ViewHolder keeps references to children views to avoid unnecessary calls
// to findViewById() on each row.
ViewHolder holder;
// When convertView is not null, we can reuse it directly, there is no need
// to reinflate it. We only inflate a new View when the convertView supplied
// by ListView is null.
if (convertView == null)
convertView = mInflater.inflate(R.layout.list_item, null);
// Creates a ViewHolder and store references to the two children views
// we want to bind data to.
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.list_view);
// Bind the data efficiently with the holder.
convertView.setTag(holder);
else
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
holder = (ViewHolder) convertView.getTag();
// If weren't re-ordering this you could rely on what you set last time
holder.text.setText(filteredData.get(position));
return convertView;
static class ViewHolder
TextView text;
public Filter getFilter()
return mFilter;
private class ItemFilter extends Filter
@Override
protected FilterResults performFiltering(CharSequence constraint)
String filterString = constraint.toString().toLowerCase();
FilterResults results = new FilterResults();
final List<String> list = originalData;
int count = list.size();
final ArrayList<String> nlist = new ArrayList<String>(count);
String filterableString ;
for (int i = 0; i < count; i++)
filterableString = list.get(i);
if (filterableString.toLowerCase().contains(filterString))
nlist.add(filterableString);
results.values = nlist;
results.count = nlist.size();
return results;
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results)
filteredData = (ArrayList<String>) results.values;
notifyDataSetChanged();
//in your Activity or Fragment where of Adapter is instantiated :
editTxt.addTextChangedListener(new TextWatcher()
@Override
public void onTextChanged(CharSequence s, int start, int before, int count)
System.out.println("Text ["+s+"]");
mSearchableAdapter.getFilter().filter(s.toString());
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after)
@Override
public void afterTextChanged(Editable s)
);
【讨论】:
嗨 Ganesh,我传递的列表不仅仅是字符串,它们是对象,在这种情况下 ItemFilter 怎么会不起作用。 ItemFilter 使用 List 的任何其他示例 我会相应修改并尝试 嗨@Ganesh Pokale,我已经实现了你所说的方式,并且在ItemFilter中它正在过滤数据并将results
返回给piublishResults,但我认为notifyDataSetChanged()不起作用。虽然在 ItemFilter 中过滤了数据,但在 List 中没有更新数据
在 notifyDataSetChanged() 之前的 PublishResults 函数中,filteredData 有应该显示的正确数据,但列表没有刷新。
您是否检查了我的适配器中过滤数据列表的所有使用情况?就像在 public int getCount() return filteredData.size(); public Object getItem(int position) return filteredData.get(position); 以上是关于无法通过 ListView 搜索,返回零结果的主要内容,如果未能解决你的问题,请参考以下文章
如何在当前活动中将搜索结果保存在 ListView (Android) 中
Android 自定义 ListView onClickListener 返回 null