如何在Android中的EditText上input时过滤ListView数据
我有一个ListView
和一个EditText
。 如何在EditText
input时过滤ListView数据?
- 将
TextWatcher
添加到EditText#addTextChangedListener
- 在
onTextChanged
添加或删除您的ListView
的适配器中的项目。 如果你是ArrayAdapter
它将有add
和remove
方法
是的你可以,只是实现这个代码:
使用以下代码在android中实现search和过滤列表:
SearchAndFilterList.java
public class SearchAndFilterList extends Activity { private ListView mSearchNFilterLv; private EditText mSearchEdt; private ArrayList<String> mStringList; private ValueAdapter valueAdapter; private TextWatcher mSearchTw; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_search_and_filter_list); initUI(); initData(); valueAdapter=new ValueAdapter(mStringList,this); mSearchNFilterLv.setAdapter(valueAdapter); mSearchEdt.addTextChangedListener(mSearchTw); } private void initData() { mStringList=new ArrayList<String>(); mStringList.add("one"); mStringList.add("two"); mStringList.add("three"); mStringList.add("four"); mStringList.add("five"); mStringList.add("six"); mStringList.add("seven"); mStringList.add("eight"); mStringList.add("nine"); mStringList.add("ten"); mStringList.add("eleven"); mStringList.add("twelve"); mStringList.add("thirteen"); mStringList.add("fourteen"); mSearchTw=new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { valueAdapter.getFilter().filter(s); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { } }; } private void initUI() { mSearchNFilterLv=(ListView) findViewById(R.id.list_view); mSearchEdt=(EditText) findViewById(R.id.txt_search); } }
自定义值适配器: ValueAdapter.java
public class ValueAdapter extends BaseAdapter implements Filterable{ private ArrayList<String> mStringList; private ArrayList<String> mStringFilterList; private LayoutInflater mInflater; private ValueFilter valueFilter; public ValueAdapter(ArrayList<String> mStringList,Context context) { this.mStringList=mStringList; this.mStringFilterList=mStringList; mInflater=LayoutInflater.from(context); getFilter(); } //How many items are in the data set represented by this Adapter. @Override public int getCount() { return mStringList.size(); } //Get the data item associated with the specified position in the data set. @Override public Object getItem(int position) { return mStringList.get(position); } //Get the row id associated with the specified position in the list. @Override public long getItemId(int position) { return position; } //Get a View that displays the data at the specified position in the data set. @Override public View getView(int position, View convertView, ViewGroup parent) { Holder viewHolder; if(convertView==null) { viewHolder=new Holder(); convertView=mInflater.inflate(R.layout.list_item,null); viewHolder.nameTv=(TextView)convertView.findViewById(R.id.txt_listitem); convertView.setTag(viewHolder); }else{ viewHolder=(Holder)convertView.getTag(); } viewHolder.nameTv.setText(mStringList.get(position).toString()); return convertView; } private class Holder{ TextView nameTv; } //Returns a filter that can be used to constrain data with a filtering pattern. @Override public Filter getFilter() { if(valueFilter==null) { valueFilter=new ValueFilter(); } return valueFilter; } private class ValueFilter extends Filter { //Invoked in a worker thread to filter the data according to the constraint. @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults results=new FilterResults(); if(constraint!=null && constraint.length()>0){ ArrayList<String> filterList=new ArrayList<String>(); for(int i=0;i<mStringFilterList.size();i++){ if(mStringFilterList.get(i).contains(constraint)) { filterList.add(mStringFilterList.get(i)); } } results.count=filterList.size(); results.values=filterList; }else{ results.count=mStringFilterList.size(); results.values=mStringFilterList; } return results; } //Invoked in the UI thread to publish the filtering results in the user interface. @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence constraint, FilterResults results) { mStringList=(ArrayList<String>) results.values; notifyDataSetChanged(); } }
}
activity_search_and_filter_list.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/txt_search" tools:context=".SearchAndFilterList" android:hint="Enter text to search" /> <ListView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/list_view" android:layout_below="@+id/txt_search"></ListView> </RelativeLayout>
list_item.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/txt_listitem"/> </RelativeLayout>
AndroidManifext.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.searchandfilterlistview" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".SearchAndFilterList" android:label="@string/title_activity_search_and_filter_list" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
我希望这段代码将有助于实现自定义search和过滤列表视图
您可以使用:
http://developer.android.com/reference/android/widget/TextView.html
addTextChangedListener( TextWatcher watcher )
弄清楚textview是什么时候改变的。 我相信每次添加或删除一个字母都应该被调用。
然后更新您的列表适配器以通过以下任一方式来删除新项目:
- 创build一个新的列表适配器,并填充满足filter或项目的项目
- 让
BaseAdapter
的子类接受filter,并在完成移除不再需要的项目后调用notifyDataSetChanged()
http://developer.android.com/reference/android/widget/BaseAdapter.html
根据EditText中的inputsearch列表视图
public class MainActivity extends Activity { private ListView lv,lv2; private EditText et; String listview_array[]={"01634 ABOHAR","080 Bangalore","011 Delhi","Dell Inspiron", "HTC One X", "HTC Wildfire S", "HTC Sense", "1234", "iPhone 4S", "Samsung Galaxy Note 800", "Samsung Galaxy S3", "MacBook Air", "Mac Mini", "MacBook Pro"}; private ArrayList<String> array_sort = new ArrayList<String>(); int textlength = 0; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv = (ListView) findViewById(R.id.ListView01); lv2 = (ListView) findViewById(R.id.ListView02); et = (EditText) findViewById(R.id.EditText01); lv.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listview_array)); int x= lv.getHeaderViewsCount (); System.out.println("x========"+x); lv.setAdapter(new ArrayAdapter<String> (MainActivity.this, android.R.layout.simple_list_item_1, listview_array)); et.addTextChangedListener(new TextWatcher() { public void afterTextChanged(Editable s) { // Abstract Method of TextWatcher Interface. } public void beforeTextChanged(CharSequence s, int start, int count, int after) { // Abstract Method of TextWatcher Interface. } public void onTextChanged(CharSequence s, int start, int before, int count) { textlength = et.getText().length(); array_sort.clear(); for (int i = 0; i < listview_array.length; i++) { if (textlength <= listview_array[i].length()) { String s2= et.getText().toString(); if(listview_array[i].toString().contains(et.getText().toString())) { array_sort.add(listview_array[i]); } } } lv.setAdapter(new ArrayAdapter<String> (MainActivity.this, android.R.layout.simple_list_item_1, array_sort)); } }); } }
对于基于类项目的自定义列表视图的search,请参考自定义列表视图上的链接实现search 。 根据您的需要修改它。
1)为列表视图创build一个自定义适配器,并创build一个removeIfMatch(String s)方法:
public void removeIfMatch(String s) { for item in adapter: if item.matches(s) { data.removeItem(item); notifyDataSetChanged(); break } }
2)创buildEditText内容更改时的callback
3)调用adapter.removeIfMatch(editText.getText())