搜索在 ArrayAdapter 和 ListView 中不起作用
Posted
技术标签:
【中文标题】搜索在 ArrayAdapter 和 ListView 中不起作用【英文标题】:Searching doesn't work in ArrayAdapter and ListView 【发布时间】:2015-06-14 22:38:13 【问题描述】:不幸的是,我无法在 ArrayAdapter 内的 ListView 中实现搜索功能。 这是我的 MainActivity 的一部分:
public class MainPageActivity extends ActionBarActivity implements View.OnClickListener
private static String TAG = "MainPageActivity";
private ListView lv_medicines;
private MedicineAdapter medicineAdapter;
private JSONParser jsonParser;
private List<Medicine> medicines;
private EditText inputSearch;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_page);
init();
inputSearch.addTextChangedListener(new TextWatcher()
@Override
public void afterTextChanged(Editable arg0)
@Override
public void beforeTextChanged(CharSequence arg0, int arg1,
int arg2, int arg3)
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2,
int arg3)
MainPageActivity.this.medicineAdapter.getFilter().filter(cs);
);
/*...*/
private void init()
lv_medicines = (ListView) findViewById(R.id.lv_medicines);
lv_medicines.setTextFilterEnabled(true);
inputSearch = (EditText) findViewById(R.id.inputSearch);
medicineAdapter = new MedicineAdapter(getApplicationContext(), hatoanyagok);
lv_medicines.setAdapter(medicineAdapter);
/*...*/
这是我的 ArrayAdapter:
public class MedicineAdapter extends ArrayAdapter<String> implements Filterable
private final Context context;
private List<String> elements;
private List<String> filteredData;
public MedicineAdapter(Context context, List<String> elements)
super(context, R.layout.row_item, elements);
this.context = context;
this.elements = elements;
this.filteredData = elements;
public String getItem(int pos)
return filteredData.get(pos);
public int getCount()
return filteredData.size();
public long getItemId(int position)
return position;
public void deleteRow(String element)
if (filteredData.contains(element))
filteredData.remove(element);
public List<String> getObjects()
return filteredData;
public void setObjects(List<String> objects)
this.elements = elements;
public List<String> getValues()
return filteredData;
private static class ViewHolder
TextView tv_medicine_name;
public View getView(int position, View convertView, ViewGroup parent)
ViewHolder viewHolder;
if (convertView == null)
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.row_item, parent, false);
viewHolder.tv_medicine_name = (TextView) convertView.findViewById(R.id.tv_medicine_name);
convertView.setTag(viewHolder);
else
viewHolder = (ViewHolder) convertView.getTag();
viewHolder.tv_medicine_name.setText(filteredData.get(position));
return convertView;
public void filter(String charText)
charText = charText.toLowerCase(Locale.getDefault());
filteredData.clear();
if (charText.length() == 0)
filteredData.addAll(elements);
else
for (String s : elements)
if (s.toLowerCase(Locale.getDefault()).contains(charText))
filteredData.add(s);
notifyDataSetChanged();
public void notifyDataSetChanged()
super.notifyDataSetChanged();
会有什么问题? 提前感谢您的回答!
【问题讨论】:
什么不起作用?您是否尝试过在 filter() 方法中设置断点并在调试模式下运行应用程序? 从 MainPageActivity 的 onTextChanged() 方法不会从 ArrayAdapter 调用 filter() 方法。 getFilter() 方法在哪里定义的? 抱歉,我的代码有点不完整,但 Vikalp 的解决方案有效。感谢您的帮助。 【参考方案1】:您需要再创建一个扩展 Filter
的类public class filter_here extends Filter
private List<String> Original_Names;
private MedicineAdapter medicineAdapter;
public filter_here(List<String> Original_Names, MedicineAdapter ma)
this.Original_Names = Original_Names;
medicineAdapter = ma;
@Override
protected FilterResults performFiltering(CharSequence constraint)
// TODO Auto-generated method stub
FilterResults Result = new FilterResults();
// if constraint is empty return the original names
if(constraint.length() == 0 )
Result.values = Original_Names;
Result.count = Original_Names.size();
return Result;
ArrayList<String> Filtered_Names = new ArrayList<String>();
String filterString = constraint.toString().toLowerCase();
String filterableString;
for(int i = 0; i<Original_Names.size(); i++)
filterableString = Original_Names.get(i);
if(filterableString.toLowerCase().contains(filterString))
Filtered_Names.add(filterableString);
Result.values = Filtered_Names;
Result.count = Filtered_Names.size();
return Result;
@Override
protected void publishResults(CharSequence constraint,FilterResults results)
// TODO Auto-generated method stub
medicineAdapter.setObjects((ArrayList<String>) results.values);
medicineAdapter.notifyDataSetChanged();
在您的适配器中创建 filter_here 类的对象并将这一行添加到适配器的构造函数中
filterObj = new filter_here(elements, this);
同时改变你的适配器类的这个方法
public void setObjects(List<String> objects)
this.filteredData = objects;
将此方法添加到您的适配器
@Override
public Filter getFilter()
// TODO Auto-generated method stub
return filterObj;
您的适配器中不需要过滤器方法。 其他一切保持原样。
【讨论】:
还有一个问题:如果我在适配器中到处使用元素变量而不是filteredData 会怎样?我需要过滤数据吗? 不,您不需要过滤数据。使用元素变量就足够了。以上是关于搜索在 ArrayAdapter 和 ListView 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
为自定义 ArrayAdapter 实现 Fiterable 接口
ArrayAdapter 未在 ListView、Android Studio 中显示添加的元素
当我尝试使用 ArrayAdapter 时,我的应用程序崩溃了
android在使用ArrayAdapter时如何分配textViewResourceId