Фильтр SearchView и набор предложений

Я очень новичок в использовании SearchView . Мне нужна функциональность, где у меня есть ActionBar для которого у меня есть Search . Когда я нажимаю «Поиск», предложения должны отображаться в списке под полем «Поиск».

Что я сделал до сих пор: добавлен поиск в menu.xml и написал код в onCreateOptionsMenu() где я инициализирую SearchView, а setSuggestionsAdapter также реализует setOnQueryTextListener .

Результат: я вхожу в приложение, нажимаю на значок поиска, он показывает предложения. Я печатаю письмо, которое сортирует соответствующие. Я печатаю 2-ю букву, в которой нет предложений. Также я закрываю поиск и открываю его снова, Клавиатура открывается, но предложения в списке не отображаются.

Что мне нужно: Фильтровать в соответствии с введенными пользователем символами. Даже если это более одного персонажа. Всегда показывайте предложения по умолчанию со всеми элементами списка или теми, которые сортируются при вводе пользователя.

Я видел в классе SearchView Android, они устанавливают текст пустым и также отклоняют предложения. Но я не хочу этого.

Я застрял здесь и не знаю, как действовать. Пожалуйста, помогите мне. Вот мой код адаптера:

 public class ExampleAdapter extends CursorAdapter implements Filterable { private ArrayList<String> items; private ArrayList<String> orig; public ExampleAdapter(Context context, Cursor cursor, ArrayList<String> items) { super(context, cursor, false); this.items = new ArrayList<String>(); this.items = items; orig = new ArrayList<String>(); orig.addAll(items); } @Override public int getCount() { return items.size(); } @Override public Filter getFilter() { return new Filter() { @Override protected FilterResults performFiltering(CharSequence constraint) { constraint = constraint.toString().toLowerCase(); FilterResults result = new FilterResults(); if (constraint != null && constraint.toString().length() > 0) { List<String> founded = new ArrayList<String>(); for (int i = 0, l = orig.size(); i < l; i++) { if (orig.get(i) .toString() .toLowerCase() .startsWith( constraint.toString().toLowerCase())) founded.add(orig.get(i)); } result.values = founded; result.count = founded.size(); } else { synchronized (this) { result.values = orig; result.count = orig.size(); } } return result; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { items.clear(); items = new ArrayList<String>(); items = (ArrayList<String>) results.values; notifyDataSetChanged(); } }; } @Override public void bindView(View view, Context context, Cursor cursor) { ViewHolder holder = (ViewHolder) view.getTag(); holder.textView.setText(items.get(cursor.getPosition())); } public class ViewHolder { public TextView textView; } @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { ViewHolder holder = new ViewHolder(); View v = null; LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = inflater.inflate(R.layout.item, parent, false); holder.textView = (TextView) v.findViewById(R.id.text); v.setTag(holder); return v; } } 

Код в моей деятельности относится к Меню, где у меня есть searchview:

 private String[] columns = new String[] { "_id", "text" }; private SearchView searchView; private SearchManager manager; private ExampleAdapter aptr; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); MenuItem searchItem = menu.findItem(R.id.action_search); searchView = (SearchView) MenuItemCompat.getActionView(searchItem); setSearchTextColour(searchView); setSearchIcons(searchView); searchView.setQueryHint(Html.fromHtml("<font color = #ffffff>" + getResources().getString(R.string.search_store) + "</font>")); searchView.setSearchableInfo(manager .getSearchableInfo(getComponentName())); Object[] temp = new Object[] { 0, "default" }; final MatrixCursor cursor = new MatrixCursor(columns); for (int i = 0; i < alStoreNames.size(); i++) { temp[0] = i; temp[1] = alStoreNames.get(i); cursor.addRow(temp); } aptr = new ExampleAdapter(MainActivity.this, cursor, alStoreNames); searchView.setSuggestionsAdapter(aptr); searchView.setOnQueryTextListener(new OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String arg0) { if (!TextUtils.isEmpty(arg0)) { aptr.getFilter().filter(arg0.toString()); } return true; } @Override public boolean onQueryTextChange(String arg0) { return false; } }); searchView.setOnSuggestionListener(new OnSuggestionListener() { @Override public boolean onSuggestionSelect(int arg0) { return false; } @Override public boolean onSuggestionClick(int position) { String suggestion = getSuggestion(position); db.openDatabase(); String studentId = db.getStudentIdFromName(suggestion); String studentImg = db.getStudentImgFromName(suggestion); db.closeDatabase(); Log.e("Sp", " On Click name -> " + aptr.getItem(position).toString() + " : " + aptr.getCursor().getString(0) + " : " + suggestion); Intent i = new Intent(MainActivity.this, ExampleActivity.class); i.putExtra("studentId", studentId); i.putExtra("studentName", suggestion); i.putExtra("studentImg", studentImg); startActivity(i); return true; } }); return true; } private String getSuggestion(int position) { Cursor cursor = (Cursor) searchView.getSuggestionsAdapter().getItem( position); String suggest1 = cursor.getString(cursor.getColumnIndex("text")); return suggest1; } private void setSearchTextColour(SearchView searchView) { Field qTextField; try { qTextField = SearchView.class.getDeclaredField("mQueryTextView"); qTextField.setAccessible(true); SearchAutoComplete searchPlate = (SearchAutoComplete) qTextField .get(searchView); searchPlate.setTextColor(getResources().getColor(R.color.white)); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } private void setSearchIcons(SearchView searchView) { try { Field searchField = SearchView.class .getDeclaredField("mCloseButton"); searchField.setAccessible(true); ImageView closeBtn = (ImageView) searchField.get(searchView); closeBtn.setImageResource(R.drawable.close); Field searchField1 = SearchView.class .getDeclaredField("mSearchButton"); searchField1.setAccessible(true); ImageView searchButton = (ImageView) searchField1.get(searchView); searchButton.setImageResource(R.drawable.ic_action_search); } catch (NoSuchFieldException e) { Log.e("SearchView", e.getMessage(), e); } catch (IllegalAccessException e) { Log.e("SearchView", e.getMessage(), e); } } 

Мне кажется, что часть проблемы заключается в отсутствии метода getItem ().

Если вы посмотрите на исходный код адаптера курсора, getItem () получит данные из курсора, а не из вашего отфильтрованного списка, вы хотите получить данные из вашего отфильтрованного списка!

Попробуй это:

 @Override public Object getItem(int position) { if (position < items.size()) { return items.get(position); } else { return null; } } 

Я забыл добавить, вам также нужно изменить это:

 private String getSuggestion(int position) { String suggest1 = (String) searchView.getSuggestionsAdapter().getItem(position); return suggest1; } 

И чтобы закрыть все, сначала добавьте это в меню createOptions:

 @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); MenuItem searchItem = menu.findItem(R.id.action_search); searchView = (SearchView) MenuItemCompat.getActionView(searchItem); searchView.setIconifiedByDefault(true); //this line ... 

Затем добавьте это в onSuggestionClick:

  @Override public boolean onSuggestionClick(int position) { String suggestion = getSuggestion(position); db.openDatabase(); String studentId = db.getStudentIdFromName(suggestion); String studentImg = db.getStudentImgFromName(suggestion); db.closeDatabase(); Log.e("Sp", " On Click name -> " + aptr.getItem(position).toString() + " : " + aptr.getCursor().getString(0) + " : " + suggestion); searchView.setIconified(true);//this line Intent i = new Intent(MainActivity.this,ExampleActivity.class); i.putExtra("studentId", studentId); i.putExtra("studentName", suggestion); i.putExtra("studentImg", studentImg); startActivity(i); return true; } 

Немного объяснения. Когда вы вызываете setIconified, он либо очистит текст вашего searchView, либо свернет его, в зависимости от состояния по умолчанию. То, что мы там делали, было настроено на состояние по умолчанию, поэтому, когда мы вызываем метод setIconified, он очищает текст и сворачивает представление!

Привет, я нашел некоторые проблемы с вашим кодом. Пожалуйста, попробуйте мой путь. Заменить publishResults of ExampleAdapter

  @Override protected void publishResults(CharSequence constraint, FilterResults results) { items.clear(); // items = new ArrayList<String>(); //items = (ArrayList<String>) results.values; items.addAll((ArrayList<String>) results.values); notifyDataSetChanged(); } 

А ТАКЖЕ

  searchView.setOnQueryTextListener(new OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String arg0) { if (!TextUtils.isEmpty(arg0)) { aptr.getFilter().filter(arg0.toString()); } return true; } @Override public boolean onQueryTextChange(String arg0) { if (!TextUtils.isEmpty(arg0)) { aptr.getFilter().filter(arg0.toString()); return true; } return false; } }); 

Попробуйте передать значение поиска, чтобы фильтр даже был пуст:

 @Override public boolean onQueryTextSubmit(String arg0) { aptr.getFilter().filter(arg0.toString()); return true; } 

Установите список по умолчанию для адаптера, если поиск не совпадает или значение поиска пустое:

 @Override public Filter getFilter() { return new Filter() { @Override protected FilterResults performFiltering(CharSequence constraint) { constraint = constraint.toString().toLowerCase(); FilterResults result = new FilterResults(); if (constraint != null && constraint.toString().length() > 0) { List<String> founded = new ArrayList<String>(); for (int i = 0, l = orig.size(); i < l; i++) { if (orig.get(i).toString().toLowerCase().startsWith(constraint.toString().toLowerCase())) founded.add(orig.get(i)); } if(founded.size()>0){ result.values = founded; result.count = founded.size(); }else{ result.values = orig; result.count = orig.size(); } } else { result.values = orig; result.count = orig.size(); } return result; }