列表视图过滤Android
我已经在android中创build了一个列表视图,我想在列表上方添加编辑文本,当用户input文本时,列表将根据用户input进行过滤
任何人都可以告诉我,如果有一种方法来过滤在Android的列表适配器?
是。 在你的列表视图的顶部的aml布局文件中添加一个EditText。 而在你的活动/片段..
lv = (ListView) findViewById(R.id.list_view); inputSearch = (EditText) findViewById(R.id.inputSearch); // Adding items to listview adapter = new ArrayAdapter<String>(this, R.layout.list_item, R.id.product_name, products); lv.setAdapter(adapter); inputSearch.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) { // When user changed the Text MainActivity.this.adapter.getFilter().filter(cs); } @Override public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { } @Override public void afterTextChanged(Editable arg0) {} });
这里的基本function是将OnTextChangeListener添加到您的编辑文本中,并在其callback方法应用筛选器中添加到您的列表视图的适配器中。
编辑
要获得filter到您的自定义BaseAdapter,您将需要实现Filterable接口。
class CustomAdapter extends BaseAdapter implements Filterable { public View getView(){ ... } public Integer getCount() { ... } @Override public Filter getFilter() { Filter filter = new Filter() { @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence constraint, FilterResults results) { arrayListNames = (List<String>) results.values; notifyDataSetChanged(); } @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults results = new FilterResults(); ArrayList<String> FilteredArrayNames = new ArrayList<String>(); // perform your search here using the searchConstraint String. constraint = constraint.toString().toLowerCase(); for (int i = 0; i < mDatabaseOfNames.size(); i++) { String dataNames = mDatabaseOfNames.get(i); if (dataNames.toLowerCase().startsWith(constraint.toString())) { FilteredArrayNames.add(dataNames); } } results.count = FilteredArrayNames.size(); results.values = FilteredArrayNames; Log.e("VALUES", results.values.toString()); return results; } }; return filter; } }
在perfromFiltering()内部,您需要将search查询与数据库中的值进行实际比较。 它将把结果传递给publishResults()方法。
实现您的适配器可筛选:
public class vJournalAdapter extends ArrayAdapter<JournalModel> implements Filterable{ private ArrayList<JournalModel> items; private Context mContext; ....
然后创build你的Filter类:
private class JournalFilter extends Filter{ @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults result = new FilterResults(); List<JournalModel> allJournals = getAllJournals(); if(constraint == null || constraint.length() == 0){ result.values = allJournals; result.count = allJournals.size(); }else{ ArrayList<JournalModel> filteredList = new ArrayList<JournalModel>(); for(JournalModel j: allJournals){ if(j.source.title.contains(constraint)) filteredList.add(j); } result.values = filteredList; result.count = filteredList.size(); } return result; } @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence constraint, FilterResults results) { if (results.count == 0) { notifyDataSetInvalidated(); } else { items = (ArrayList<JournalModel>) results.values; notifyDataSetChanged(); } } }
这样,您的适配器是可筛选的,您可以将筛选器项目传递到适配器的筛选器并完成工作。 我希望这会有所帮助。
如果有人对这个主题仍然感兴趣,我发现筛选列表的最好方法是创build一个通用的Filter类,并将其与Java老派SDK包中包含的一些基本reflection/generics技术一起使用。 以下是我所做的:
public class GenericListFilter<T> extends Filter { /** * Copycat constructor * @param list the original list to be used */ public GenericListFilter (List<T> list, String reflectMethodName, ArrayAdapter<T> adapter) { super (); mInternalList = new ArrayList<>(list); mAdapterUsed = adapter; try { ParameterizedType stringListType = (ParameterizedType) getClass().getField("mInternalList").getGenericType(); mCompairMethod = stringListType.getActualTypeArguments()[0].getClass().getMethod(reflectMethodName); } catch (Exception ex) { Log.w("GenericListFilter", ex.getMessage(), ex); try { if (mInternalList.size() > 0) { T type = mInternalList.get(0); mCompairMethod = type.getClass().getMethod(reflectMethodName); } } catch (Exception e) { Log.e("GenericListFilter", e.getMessage(), e); } } } /** * Let's filter the data with the given constraint * @param constraint * @return */ @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults results = new FilterResults(); List<T> filteredContents = new ArrayList<>(); if ( constraint.length() > 0 ) { try { for (T obj : mInternalList) { String result = (String) mCompairMethod.invoke(obj); if (result.toLowerCase().startsWith(constraint.toString().toLowerCase())) { filteredContents.add(obj); } } } catch (Exception ex) { Log.e("GenericListFilter", ex.getMessage(), ex); } } else { filteredContents.addAll(mInternalList); } results.values = filteredContents; results.count = filteredContents.size(); return results; } /** * Publish the filtering adapter list * @param constraint * @param results */ @Override protected void publishResults(CharSequence constraint, FilterResults results) { mAdapterUsed.clear(); mAdapterUsed.addAll((List<T>) results.values); if ( results.count == 0 ) { mAdapterUsed.notifyDataSetInvalidated(); } else { mAdapterUsed.notifyDataSetChanged(); } } // class properties private ArrayAdapter<T> mAdapterUsed; private List<T> mInternalList; private Method mCompairMethod; }
之后,您唯一需要做的就是创build一个filter作为成员类(可能在视图的“onCreate”中)传递适配器引用,您的列表以及要过滤的方法:
this.mFilter = new GenericFilter<MyObjectBean> (list, "getName", adapter);
现在唯一缺less的是重写适配器类中的“getFilter”方法:
@Override public Filter getFilter () { return MyViewClass.this.mFilter; }
全做完了! 你应该成功地过滤你的列表 – 当然,你也应该实现你的filteralgorithm描述你的需要的最佳方式,下面的代码只是一个例子。 。 希望它帮助,照顾。