SearchClick OnCloseListener не работает

Я пытаюсь добавить поддержку SearchView в Android 3.0+ ActionBar, но я не могу заставить OnCloseListener работать.

Вот мой код:

 @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu, menu); searchView = (SearchView) menu.findItem(R.id.search_textbox).getActionView(); searchView.setOnQueryTextListener(new OnQueryTextListener() { @Override public boolean onQueryTextChange(String newText) { searchLibrary(newText); return false; } @Override public boolean onQueryTextSubmit(String query) { return false; } }); searchView.setOnCloseListener(new OnCloseListener() { @Override public boolean onClose() { System.out.println("Testing. 1, 2, 3..."); return false; } }); return true; } 

Поиск работает отлично, и каждый работает, за исключением OnCloseListener . В Logcat ничего не печатается. Вот Logcat, когда я нажимаю кнопку «Закрыть»:

 02-17 13:01:52.914: I/TextType(446): TextType = 0x0 02-17 13:01:57.344: I/TextType(446): TextType = 0x0 02-17 13:02:02.944: I/TextType(446): TextType = 0x0 

Я просмотрел документацию и образцы, но ничего не изменило. Я запускаю его на Asus Transformer Prime и Galaxy Nexus, как на Ice Cream Sandwich. Есть идеи?

Обновить:

Да – System.out.println() работает. Вот доказательство:

  @Override public boolean onQueryTextChange(String newText) { System.out.println(newText + "hello"); searchLibrary(newText); return false; } 

Результаты в этом Logcat:

 02-17 13:04:20.094: I/System.out(21152): hello 02-17 13:04:24.914: I/System.out(21152): thello 02-17 13:04:25.394: I/System.out(21152): tehello 02-17 13:04:25.784: I/System.out(21152): teshello 02-17 13:04:26.064: I/System.out(21152): testhello 

Solutions Collecting From Web of "SearchClick OnCloseListener не работает"

Я также встречаю эту проблему, и у меня нет выбора, кроме как отказаться от «oncloselistener». Вместо этого вы можете получить свой пункт меню, а затем setOnActionExpandListener . Затем переопределите методы unimplents.

 @Override public boolean onMenuItemActionExpand(MenuItem item) { // TODO Auto-generated method stub Log.d("*******","onMenuItemActionExpand"); return true; } @Override public boolean onMenuItemActionCollapse(MenuItem item) { //do what you want to when close the sesarchview //remember to return true; Log.d("*******","onMenuItemActionCollapse"); return true; } 

Для Android API 14+ (ICS и выше) используйте этот код:

 // When using the support library, the setOnActionExpandListener() method is // static and accepts the MenuItem object as an argument MenuItemCompat.setOnActionExpandListener(menuItem, new OnActionExpandListener() { @Override public boolean onMenuItemActionCollapse(MenuItem item) { // Do something when collapsed return true; // Return true to collapse action view } @Override public boolean onMenuItemActionExpand(MenuItem item) { // Do something when expanded return true; // Return true to expand action view } }); 

Для получения дополнительной информации: http://developer.android.com/guide/topics/ui/actionbar.html#ActionView

Ссылка: onActionCollapse / onActionExpand

Для этой проблемы я придумал что-то вроде этого,

 private SearchView mSearchView; @TargetApi(14) @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.conversation_index_activity_menu, menu); mSearchView = (SearchView) menu.findItem(R.id.itemSearch).getActionView(); MenuItem menuItem = menu.findItem(R.id.itemSearch); int currentapiVersion = android.os.Build.VERSION.SDK_INT; if (currentapiVersion >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) { menuItem.setOnActionExpandListener(new OnActionExpandListener() { @Override public boolean onMenuItemActionCollapse(MenuItem item) { // Do something when collapsed Log.i(TAG, "onMenuItemActionCollapse " + item.getItemId()); return true; // Return true to collapse action view } @Override public boolean onMenuItemActionExpand(MenuItem item) { // TODO Auto-generated method stub Log.i(TAG, "onMenuItemActionExpand " + item.getItemId()); return true; } }); } else { // do something for phones running an SDK before froyo mSearchView.setOnCloseListener(new OnCloseListener() { @Override public boolean onClose() { Log.i(TAG, "mSearchView on close "); // TODO Auto-generated method stub return false; } }); } return super.onCreateOptionsMenu(menu); } 

Я столкнулся с той же проблемой на Android 4.1.1. Похоже, что это известная ошибка: https://code.google.com/p/android/issues/detail?id=25758

Во всяком случае, в качестве обходного пути я использовал прослушиватель изменений состояния (когда SearchView отсоединен от панели действий, он также закрыт).

 view.addOnAttachStateChangeListener(new OnAttachStateChangeListener() { @Override public void onViewDetachedFromWindow(View arg0) { // search was detached/closed } @Override public void onViewAttachedToWindow(View arg0) { // search was opened } }); 

Над кодом хорошо работал в моем случае.


Я отправляю такой же ответ здесь: https://stackoverflow.com/a/24573266/2162924

Я закончил тем, что использовал немного взлома, который хорошо работает для моей цели – не уверен, что он будет работать со всеми целями. Во всяком случае, я делаю проверку, чтобы выяснить, пустой ли поисковый запрос. Это действительно не связано с SearchView OnCloseListener хотя это все еще не работает!

 searchView.setOnQueryTextListener(new OnQueryTextListener() { @Override public boolean onQueryTextChange(String newText) { if (newText.length() > 0) { // Search } else { // Do something when there's no input } return false; } @Override public boolean onQueryTextSubmit(String query) { return false; } }); 

Ну, это решило мою проблему:

Пункт меню с showAsAction="always"

 <item android:id="@+id/action_search" android:icon="@drawable/ic_action_search" android:title="Search" app:actionViewClass="android.support.v7.widget.SearchView" app:showAsAction="always"/> 

И в деятельности

 searchView.setOnCloseListener(new OnCloseListener() { @Override public boolean onClose() { Log.i("SearchView:", "onClose"); searchView.onActionViewCollapsed(); return false; } }); 

Чтобы заставить OnCloseListener работать, убедитесь, что showAsAction always в элементе меню поиска.

 <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context=".SearchActivity"> <item android:id="@+id/search" android:title="@string/search" android:icon="@drawable/ic_search_toolbar" app:showAsAction="always" app:actionViewClass="android.support.v7.widget.SearchView"/> </menu> 

Для проблемы MenuItemCompat я добавил ViewTreeObserver для отслеживания состояния видимости. Вы можете проверить мой ответ здесь: https://stackoverflow.com/a/28762632/1633609

Причина, по которой OnCloseListener не вызывается, заключается в том, что в коде Android есть ошибка – прослушиватель вызывается только в том случае, если вы также вызываете setIconifiedByDefault(true) .

Кажется уже старой веткой, но я думал, что у меня такая же проблема API 18 в первом начале. После того, как googled вокруг, нашел эту нить, еще один час прочитал javadoc, попытался и ошибся в том, что я не претендую на полное понимание в javadoc, следующая работа для меня сейчас:

 searchView.setIconifiedByDefault(true); // OnQueryTextListener @Override public boolean onQueryTextSubmit(String query) { Log.d(tag, "onQueryTextSubmit: " + query); return true; } @Override public boolean onQueryTextChange(String query) { Log.d(tag, "onQueryTextChange: " + query); return true; } // OnCloseListener @Override public boolean onClose() { Log.w(tag, "onClose: "); return false; } 

Я играл с истинным / ложным, что-то меняет ситуацию, и теперь это работает для меня. Надеюсь, это может сэкономить время.

Я столкнулся с той же проблемой, когда onCloseListener не вызывается для SearchView. Поймите из проблемы с ошибкой, поднятой в 25758 , и некоторых сообщений, которые я прочитал, чтобы вызвать onCloseListener, вам нужно установить:

 searchView.setIconifiedByDefault(true); 

Но для моего случая я хотел, чтобы поиск был открыт и не отображался все время. Мне удалось решить эту проблему, добавив еще одну строку ниже:

 @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.search_bar, menu); SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); searchView = (SearchView) menu.findItem(R.id.search).getActionView(); searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); searchView.setOnQueryTextListener(queryTextListener); searchView.setIconifiedByDefault(true); searchView.setIconified(false); return true; } 

SearchView.setIconified (false) приведет к тому, что searchView откроется, несмотря на то, что в предыдущей строке значение по умолчанию указано в true. Таким образом, мне удалось найти и SearchView, который открывается все время и вызывает его onCloseListener.

В Android нет консоли для входа в систему. Вместо этого используйте фреймворк андроида:

 Log.d("Test Tag", "Testing. 1, 2, 3..."); 

См. Также этот вопрос: Почему в Android не работает «System.out.println»?

Существует два общих шаблона для SearchView.setOnCloseListener() . Это действительно верно для всех слушателей, но я конкретно обращаюсь к вашему вопросу. Первый способ – создать функцию прослушивателя и прикрепить ее к переменной-члену, а вторая – сделать реализацию класса интерфейсом и присвоить ему функцию-член.

Создание объекта-слушателя выглядит следующим образом:

 private SearchView mSearchView; private final SearchView.OnCloseListener mOnCloseListener = new SearchView.OnCloseListener() { public boolean onClose() { doStuff(); return myBooleanResult; } }; mSearchView.setOnCloseListener(mOnCloseListener); 

Реализация слушателя на уровне класса выглядит следующим образом:

 public class MyClass implements OnCloseListener { private SearchView mSearchView; public MyClass(...) { mSearchView.setOnCloseListener(this); } @Override public boolean onClose() { doStuff(); return false; } } 

Я не видел примеров, которые создавали OnCloseListener , как и в вашем вопросе.