android - example - searchview ejemplo
El reemplazo de fragmentos desencadena onQueryTextChange en searchview (5)
Después de 2 días de buscar en Google, obtuve la solución que definitivamente te ayudará.
Acabo de cut and pasted
código de onCreateOptionMenu()
a onPrepareOptionMenu()
No sé por qué sucede, creo que el oyente de searchView
no va a ser NULL
por la forma en que puede cambiar su código de esta manera.
@Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
getSherlockActivity().getSupportMenuInflater().inflate(R.menu.menu_all_order, menu);
searchView = (SearchView) menu.findItem(R.id.menu_all_order_search).getActionView();
searchView.setInputType(InputType.TYPE_CLASS_NUMBER);
searchView.setQueryHint("Enter Order No");
searchView.setOnQueryTextListener(this);
}
y eliminar:
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
}
Gracias :)
Así es como navego por mi aplicación:
- Abrir fragmento con lista
- Filtra la lista por un texto ingresado en searchview
- Toque en listitem (fragmento de lista se reemplaza por fragmento de detalle)
- Navegar hacia atrás (el fragmento de detalle se reemplaza por el fragmento de lista)
Cuando navego desde la lista hasta el fragmento de detalle, quiero mantener el filtro actual de la vista de búsqueda en una variable de cadena. Almaceno el valor de la vista de búsqueda cuando se ejecuta onQueryTextChange.
El problema: no puedo almacenar el valor de filtro real porque se llama a onQueryTextChange cuando navego de la lista a los detalles porque algo borra el texto de la vista de búsqueda.
// ...
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
return false;
}
@Override
public boolean onQueryTextChange(String s) {
searchReceived(s);
return true;
}
});
// ...
public void searchReceived(String searchQuery)
{
this.stateHolder.searchQuery = searchQuery;
// more code...
}
Cuando quiero restaurar el filtro cuando navego hacia atrás, simplemente se filtra con una cadena vacía porque el valor incorrecto se almacenó en this.stateHolder.searchQuery
.
Apilar:
onQueryTextChange():139, EmployeeListFragment$1 {com.example.exampleapp.fragment}
onTextChanged():1153, SearchView {android.widget}
access$2000():92, SearchView {android.widget}
onTextChanged():1638, SearchView$11 {android.widget}
sendOnTextChanged():7408, TextView {android.widget}
setText():3816, TextView {android.widget}
setText():3671, TextView {android.widget}
setText():80, EditText {android.widget}
setText():3646, TextView {android.widget}
setQuery():511, SearchView {android.widget}
onActionViewCollapsed():1250, SearchView {android.widget}
collapseItemActionView():1662, ActionBarView$ExpandedActionViewMenuPresenter {com.android.internal.widget}
collapseItemActionView():1258, MenuBuilder {com.android.internal.view.menu}
clear():521, MenuBuilder {com.android.internal.view.menu}
doInvalidatePanelMenu():789, PhoneWindow {com.android.internal.policy.impl}
run():221, PhoneWindow$1 {com.android.internal.policy.impl}
¿Cómo puedo evitar que la vista de búsqueda sea borrada por el sistema al navegar?
Gracias.
El problema es que la barra de acción (y los subcomponentes) se contraen cuando se reemplaza el fragmento que lo contiene. Cuando esto sucede, la consulta SearchView se borra como se ve en onActionViewCollapsed . Las soluciones incluyen:
Evitar el colapso
Eliminar setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
desde el código de creación de searchview o android:showAsAction="collapseActionView"
desde su código xml.
Esto afectará cómo / cuándo se muestran los botones de cerrar / búsqueda de voz de la vista al intentar colapsarla
También sería posible evitar el colapso anulando el método onActionViewCollapsed () de SearchView para no hacer nada, pero lograría lo mismo.
Ignorar los cambios de consulta cuando sea apropiado
Cuando el fragmento no es válido (se está reemplazando), ignore los cambios de consulta que, de lo contrario, harían que el fragmento alterara el diseño o el texto de la consulta guardada (el cambio del diseño provocaría una excepción si el fragmento no tiene contenido de visualización).
public boolean onQueryTextChange(String newText) {
if (!isVisible()) {
// The fragment was replaced so ignore
return true;
}
// Text was actually changed, perform search
return true;
}
Esta sería la mejor opción, ya que no afecta la funcionalidad de la vista de búsqueda.
Esta es mi solución:
@Override
public boolean onQueryTextChange(final String newText) {
if (searchTF.isIconified())
return false;
// put the "real" onQueryTextChange actions here
return true;
}
Veo que aún no has encontrado una solución, tengo el mismo problem publicado problem :
Descubrí que cuando se llama a invalidateOptionsMenu
también se llama al método onQueryTextChange
porque la Vista onQueryTextChange
dispatchRestoreInstanceState
con el valor anterior después de haber borrado la búsqueda, por ejemplo. ¿Llamas invalidateOptionsMenu
quizás?
Tal vez, dentro de onQueryTextChange
, puede verificar un valor booleano en algún estado actual de los objetos de su aplicación para saber si se debe ejecutar el contenido del método . En mi caso, uso mDrawerLayout.isDrawerOpen(..)
para permitir la búsqueda.
También puede implementar el SearchView.OnQueryTextListener
en cada clase que use, en un Fragment
o en la clase de actividad principal, en algún lugar de la clase podría establecer una variable de módulo booleana que verificará dentro de onQueryTextChange.
showAsAction
atributo del elemento del menú showAsAction
de android:showAsAction="always|collapseActionView"
a android:showAsAction="always"
. Ahora, el aspecto y el comportamiento de la vista de búsqueda ha cambiado un poco, ¡pero la función de búsqueda no se borra!
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/actionSearch"
android:icon="@android:drawable/ic_menu_search"
android:actionViewClass="android.widget.SearchView"
android:showAsAction="always"
android:title="@android:string/search_go"
/>
</menu>