android android-3.0-honeycomb android-4.0 android-actionbar

android - SearchView''s OnCloseListener no funciona



android-3.0-honeycomb android-4.0 (15)

Estoy tratando de agregar compatibilidad para SearchView en Android 3.0+ ActionBar, pero no puedo hacer que OnCloseListener funcione.

Aquí está mi código:

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

La búsqueda funciona bien y todo funciona, excepto OnCloseListener . Nada se imprime en Logcat. Aquí está el Logcat para cuando estoy presionando el botón "Cerrar":

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

Revisé la documentación y las muestras, pero nada pareció cambiarlo. Lo estoy ejecutando en un Asus Transformer Prime y un Galaxy Nexus, ambos en Ice Cream Sandwich. ¿Algunas ideas?

Actualizar:

Sí - System.out.println() funciona. Aquí hay una prueba:

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

Resultados en este 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


Bueno, esto resolvió mi problema:

showAsAction="always" menú con 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"/>

y en actividad

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


Cree el elemento de menú con la app:showAsAction establecido en always.

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

Al crear SearchView en el método onCreateOptionsMenu , haga algo similar

inflater.inflate(R.menu.menu_search, menu); final MenuItem item = menu.findItem(R.id.action_search); final SearchView search = (SearchView) item.getActionView(); search.setQueryHint(getString(R.string.search_brand_item)); search.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { // add your code return false; } @Override public boolean onQueryTextChange(String newText) { // add your code return false; } }); search.setOnCloseListener(new SearchView.OnCloseListener() { @Override public boolean onClose() { // add your code here return false; } }); search.setIconifiedByDefault(true); // make sure to set this to true

El search.setIconifiedByDefault(true) debe establecerse en true para llamar al método onClose() en el SearchView.OnCloseListener() creado anteriormente.


Es una solución pero me ha funcionado

searchView.setOnQueryTextListener(new android.widget.SearchView.OnQueryTextListener() { String lastText; @Override public boolean onQueryTextChange(final String newText) { if (lastText != null && lastText.length() > 1 && newText.isEmpty()) { // close ctn clicked return true; } }


Hay dos patrones comunes para SearchView.setOnCloseListener() . Esto es realmente cierto para todos los oyentes, pero estoy abordando su pregunta específicamente. La primera es crear una función de escucha y adjuntarla a una variable de miembro, y la segunda es hacer que la clase implemente la interfaz y que el controlador sea una función miembro.

La creación de un objeto detector se ve así:

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

La implementación del oyente a nivel de clase se ve así:

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

No he visto ningún ejemplo que cree el OnCloseListener ad-hoc, como lo hizo en su pregunta.


He encontrado el mismo problema con onCloseListener que no invoca para SearchView. Comprenda del problema de los errores planteado en 25758 , y algunas publicaciones que he leído, para invocar aCloseListener, debe configurar:

searchView.setIconifiedByDefault(true);

Pero para mi caso, quería que la vista de búsqueda se abriera y no se iconizara todo el tiempo. Me las arreglé para resolver esto agregando una línea más a continuación:

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

El searchView.setIconified (false) hará que SearchView se abra, a pesar de establecer el valor predeterminado para iconified en true en la línea anterior. De esta manera, logré tener un SearchView que se abre todo el tiempo y que invoque onCloseListener.


La razón por la que no se llama a OnCloseListener es porque hay un error en el código de Android; solo se llama al oyente si también se llama a setIconifiedByDefault(true) .


Me encontré con el mismo problema en Android 4.1.1. Parece que se trata de un error conocido: https://code.google.com/p/android/issues/detail?id=25758

De todos modos, como solución alternativa utilicé el detector de cambios de estado (cuando SearchView está separado de la barra de acciones, también se cierra obviamente).

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

El código anterior funcionó bien en mi caso.

Publiqué la misma respuesta aquí: https://.com/a/24573266/2162924



Para Android API 14+ (ICS y superior) use este código:

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

Para más información: http://developer.android.com/guide/topics/ui/actionbar.html#ActionView

Ref: onActionCollapse/onActionExpand


Para el problema de MenuItemCompat , agregué ViewTreeObserver para rastrear el estado de visibilidad. Puede verificar mi respuesta aquí: https://.com/a/28762632/1633609


Para este problema, se me ocurrió algo como esto,

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


Para que OnCloseListener funcione, asegúrese de que showAsAction esté configurado always en el elemento del menú de búsqueda.

<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>


También me encuentro con este problema, y ​​no tengo más remedio que renunciar a "oncloselistener". En cambio, puede obtener su elemento de menú, luego setOnActionExpandListener . Luego, anule los métodos de 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; }


Terminé usando un truco, que funciona bien para mi propósito, no estoy seguro de que funcione con todos los propósitos. De todos modos, estoy haciendo una comprobación para ver si la consulta de búsqueda está vacía. OnCloseListener embargo, esto no está realmente relacionado con OnCloseListener , ¡eso aún no funciona!

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


parece un hilo viejo, pero pensé que tuve el mismo problema API 18 en el primer comienzo. Después de buscar en Google, encontré este hilo, otra hora leyó el javadoc probado y con errores para algo que no pretendo entender completamente en javadoc, el siguiente trabajo para mí ahora:

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

Jugué con verdadero / falso un poco, que de alguna manera hace la diferencia, y ahora funciona para mí. Con suerte, podría ahorrarle tiempo a alguien.