Список поиска Android при наборе текста

Как я могу создать панель поиска, где, пока я печатаю результаты, отображаются в ListView в котором я ищу?

Например, у меня есть список с 20 строками. Я нажимаю клавишу поиска и появляется панель. Я хочу, когда я напечатаю 3 слова или более, поиск начнет показываться, показывая результаты в представлении списка (в качестве фильтра: отображаются только строки в списке, соответствующие типу)

Solutions Collecting From Web of "Список поиска Android при наборе текста"

Вы не можете сделать это с помощью панели поиска. Но listview имеет возможность фильтровать нажатие клавиши , как это делается в контактах. Пользователь просто начинает печатать, и затем профиль фильтруется. Фильтрация на самом деле не похожа на поиск. Если в списке содержится слово foo где-то, и вы набираете oo foo, будет отфильтровано, но если вы наберете fo, он останется, даже если элемент списка – панель вызовов foo.

Вам просто нужно включить его:

 ListView lv = getListView(); lv.setTextFilterEnabled(true); 

Я не знаю, как это сделать, если у вас нет аппаратной клавиатуры. Я использую дроид и начинаю печатать, запускает список для фильтрации и показывает только соответствующие результаты.

Я считаю, что это то, что вы ищете:

http://www.java2s.com/Code/Android/2D-Graphics/ShowsalistthatcanbefilteredinplacewithaSearchViewinnoniconifiedmode.htm

Попробуйте реализовать свою активность SearchView.OnQueryTextListener

И добавьте следующие методы:

 public boolean onQueryTextChange(String newText) { if (TextUtils.isEmpty(newText)) { mListView.clearTextFilter(); } else { mListView.setFilterText(newText.toString()); } return true; } public boolean onQueryTextSubmit(String query) { return false; } 

Я использовал EditText чтобы выполнить эту работу.

Сначала я создал две копии массива для хранения списка данных для поиска:

 List<Map<String,String>> vehicleinfo; List<Map<String,String>> vehicleinfodisplay; 

Как только у меня есть данные из моего списка, я копирую его:

 for(Map<String,String>map : vehicleinfo) { vehicleinfodisplay.add(map); } 

И используйте SimpleAdapter для отображения отображаемой (скопированной) версии моих данных:

 String[] from={"vehicle","dateon","dateoff","reg"}; int[] to={R.id.vehicle,R.id.vehicledateon,R.id.vehicledateoff,R.id.vehiclereg}; listadapter=new SimpleAdapter(c,vehicleinfodisplay,R.layout.vehiclelistrow,from,to); vehiclelist.setAdapter(listadapter); 

Затем я добавил TextWatcher в EditText который отвечает на событие afterTextChanged , очистив отображаемую версию списка, а затем добавив обратно только элементы из другого списка, соответствующие критериям поиска (в этом случае поле «reg» содержит поиск строка). Когда список отображений заполняется фильтрованным списком, я просто вызываю notifyDataSetChanged списка.

 searchbox.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable s) { vehicleinfodisplay.clear(); String search=s.toString(); for(Map<String,String>map : vehicleinfo) { if(map.get("reg").toLowerCase().contains(search.toLowerCase())) vehicleinfodisplay.add(map); listadapter.notifyDataSetChanged(); } }; ... other overridden methods can go here ... }); 

Надеюсь, это кому-то поможет.

Используйте следующий код для реализации списка поиска и фильтрации в android:

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); } } 

Пользовательский адаптер Value: 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> 

Я надеюсь, что этот код будет полезен для реализации пользовательского поиска и списка фильтров

Лучший способ – использовать встроенную панель поиска или SearchManager, переопределив onSearchRequested в операции поиска. Вы можете установить источник данных для поиска, чтобы получить автоматическое выпадение результатов, или вы можете просто взять вход пользователя и выполнить поиск после. Вот хороший обзор SearchManager – это плюс, есть рабочая демонстрация в проекте API Demos com.example.android.apis.app.SearchQueryResult

 @Override public boolean onSearchRequested() {