android - studio - Auto Collapse ActionBar SearchView en el teclado suave cerrar
soft keyboard android (11)
Actualmente estoy usando un elemento del menú ActionBar para mostrar un SearchView en la barra de acciones. Cuando se expande el elemento del menú de búsqueda, se muestra el teclado virtual, que es lo que quiero. Ahora, cuando el usuario presione el botón Atrás para cerrar el teclado virtual, también me gustaría colapsar el SearchView en la barra de acciones.
He intentado implementar los siguientes detectores OnKeyListener y OnFocusChangeListener en MenuItem y ActionView. También he intentado usar OnBackPressed () en la Actividad. Ninguno de los anteriores detecta cuando el botón Atrás se usa para cerrar el teclado virtual.
¿Algunas ideas?
Implementé OnActionExpandListener para saber cuándo está visible SearchView.
Debe llamar a setIconified dos veces.
Para colapsar la vista de búsqueda y cerrar el teclado.
Con la primera llamada, el texto de la vista de búsqueda se borra con el teclado de la segunda llamada y se cierra la vista de búsqueda.
Encontré una mejor solución.
searchView.setOnQueryTextFocusChangeListener().
Se llama al OnQueryTextFocusChangeListener
cuando el teclado se muestra u oculta. Se llama primero cuando se muestra el teclado y la vista de búsqueda tendrá el foco. Se llama nuevamente cuando el keyboard
está oculto y la vista de búsqueda perderá el foco, puede close search view
luego usar
menuItem.collapseActionView().
Es posible así:
private void setupSearchView(Menu menu) {
final MenuItem searchMenuItem = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) searchMenuItem.getActionView();
[...]
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
searchMenuItem.collapseActionView();
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
return true;
}
});
}
Las soluciones basadas en setOnQueryTextFocusChangeListener () no funcionaron para mí porque el evento no se inició: el searchView no perdió el enfoque cuando se envió, probablemente porque realizo la búsqueda en la misma actividad que contiene la vista de búsqueda.
De todos modos, creo que usar OnQueryTextListener es más correcto, ya que describe el evento de enviar texto de manera más precisa.
Esto es lo que hice para hacer desaparecer el teclado. Puede intentar ver si esto funciona para usted. Configuré el searchView
en invisible y luego en visible de nuevo.
//set query change listener
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener(){
@Override
public boolean onQueryTextChange(String newText) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean onQueryTextSubmit(String query) {
/**
* hides and then unhides search tab to make sure keyboard disappears when query is submitted
*/
searchView.setVisibility(View.INVISIBLE);
searchView.setVisibility(View.VISIBLE);
return false;
}
});
Expandiré la respuesta de @ user1258568 para los perezosos. Esto funcionó para mí. Tenga en cuenta que borra su consulta cuando se pierde el foco.
final MenuItem searchMenuItem = optionsMenu.findItem(R.id.search);
final SearchView searchView = (SearchView) searchMenuItem.getActionView();
searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean queryTextFocused) {
if(!queryTextFocused) {
searchMenuItem.collapseActionView();
searchView.setQuery("", false);
}
}
});
La respuesta de Jon Willis funciona muy bien. Esto es una mejora en su respuesta.
Primero, cree una nueva clase que implemente View.OnFocusChangeListener
:
public class SearchViewFocusListener implements View.OnFocusChangeListener {
private final MenuItem mMenuItem;
public SearchViewFocusListener(MenuItem menuItem) {
mMenuItem = menuItem;
}
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
mMenuItem.collapseActionView();
if (v instanceof SearchView) {
((SearchView) v).setQuery("", false);
}
}
}
}
A continuación, configure el oyente en su SearchView
:
searchView.setOnQueryTextFocusChangeListener(new SearchViewFocusListener(menuItem));
Por alguna razón, menuItem.collapseActionView()
no funcionó, así que usé searchView.setIconified(true)
lugar.
Esto da el siguiente resultado como la muestra del código.
final MenuItem searchItem = (MenuItem) menu.findItem(R.id.menu_item_search);
final SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setOnQueryTextFocusChangeListener(new SearchView.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
searchView.setIconified(true);
}
}
});
Si quiere colapsar el teclado cuando el usuario hace clic en el ícono de búsqueda en el teclado, esto se puede lograr de forma simple.
inside onquerytextsubmitted {
searchView.clearfocus()
}
Simplemente anule onBackPressed así:
@Override
public void onBackPressed() {
if (searchView.isShown()){
searchView.onActionViewCollapsed(); //collapse your ActionView
searchView.setQuery("",false); //clears your query without submit
isClosed = true; //needed to handle closed by back
} else{
super.onBackPressed();
}
}
y su onCreateOptionsMenu inflaría mSearchView así:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.menu_search, menu);
mSearchView = (SearchView) menu.findItem(R.id.menu_action_search).getActionView();
mSearchView.setOnQueryTextListener(this);
mSearchView.setOnSearchClickListener(this);
mSearchView.setOnCloseListener(this);
isClosed = true;
return true;
}
haz que tu clase implemente lo siguiente como este:
public class myActivity extends FragmentActivity implements
SearchView.OnQueryTextListener, View.OnClickListener, SearchView.OnCloseListener {
que también necesitarás:
@Override
public void onClick(View view) {
isClosed = false;
}
@Override
public boolean onClose() {
isClosed = true;
return false;
}
Tendrá que hacer que "mSearchView" y "isClosed" sean variables globales de la actividad.
Solo necesita poner el atributo "collapseActionView" en el diseño del menú
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_item_search"
android:title="@string/search"
android:iconifiedByDefault="true"
android:icon="@drawable/ic_action_search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="ifRoom|collapseActionView"/> <--this one
</menu>
Eso le dará la funcionalidad que busca por sí sola. No olvide llamar al método "clearFocus" en SearchView para cerrar el teclado una vez que envíe la consulta.
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.home_screen, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
final MenuItem searchMenuItem = menu.findItem(R.id.menu_search);
final SearchView searchView = (SearchView) searchMenuItem
.getActionView();
searchView.setIconifiedByDefault(false);
if (searchManager != null && searchView != null) {
searchView.setSearchableInfo(searchManager
.getSearchableInfo(getComponentName()));
searchView
.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
if (searchMenuItem != null) {
searchMenuItem.collapseActionView();
}// end if
if (searchView != null) {
searchView.setQuery("", false);
}// end if
}// end if
}
});
searchView
.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
/**
* hides and then unhides search tab to make sure
* keyboard disappears when query is submitted
*/
if (searchView != null) {
searchView.setVisibility(View.INVISIBLE);
searchView.setVisibility(View.VISIBLE);
}
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
// TODO Auto-generated method stub
return false;
}
});
}
return super.onCreateOptionsMenu(menu);
}