Implementación correcta de SearchView en la barra de herramientas de Android

Tengo un problema con la implementación de la búsqueda en la barra de herramientas de Android.

  1. El relleno de espacio vacío es demasiado grande.
  2. No quiero ocultar otras acciones, pero estas acciones se superponen con SearchView.
  3. El subrayado de SearchView no está visible

¿Cómo puedo solucionar los problemas mencionados anteriormente?

Introduzca aquí la descripción de la imagen

Menu.xml

<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/action_search" android:title="@string/car_num" android:icon="@drawable/ic_search_white_24dp" app:actionViewClass="android.support.v7.widget.SearchView" app:showAsAction="always" /> <item android:id="@+id/action_add_client" android:icon="@drawable/ic_account_multiple_plus" android:title="@string/action_add_client" app:showAsAction="always" /> </menu> 

fragmento

 @Override public void onCreateOptionsMenu(final Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.menu_fragment_reg_vehicles, menu); final MenuItem item = menu.findItem(R.id.action_search); searchView = (SearchView) MenuItemCompat.getActionView(item); searchView.setQueryHint("Search"); searchView.setMaxWidth(Integer.MAX_VALUE); searchView.setIconifiedByDefault(false); searchView.setOnQueryTextListener(this); searchView.setOnCloseListener(new SearchView.OnCloseListener() { @Override public boolean onClose() { setItemsVisibility(menu, item, true); return false; } }); searchView.setOnSearchClickListener(new View.OnClickListener() { @Override public void onClick(View view) { setItemsVisibility(menu, item, false); searchView.requestFocus(); } }); } 

Con respecto a su código publicado, este es el resultado:

Barra de herramientas con SearchView AppCompat de forma predeterminada

Como puede ver, hay dos márgenes a la izquierda: el contenedor del widget y el icono de ampliación. Es por eso que tienes un espacio vacío más grande que otra ventana con un título. Y los elementos del menú se empujan fuera de la barra de herramientas que, creo, es el predeterminado ActionView cuando no es un CollapseActionView por lo que llena el padre.

Desde la fuente del widget SearchView y su diseño abc_search_view.xml , intenté eliminar los márgenes adicionales y evitar empujar los demás elementos fuera de la barra de herramientas.
Pero después de muchas manipulaciones, supongo que tienes que usar un widget personalizado y / o un diseño personalizado. O para jugar con setIconifiedByDefault(true) que elimina el icono de setMaxWidth(MAX_SIZE) y su margen adicional y utilizar setMaxWidth(MAX_SIZE) donde MAX_SIZE es calculado dinámicamente por Integer.MAX_VALUE - (SIZE_OF_A_MENU_ITEM * NB_OF_MENU_ITEMS) … Pero requiere mucho trabajo para nada. Así que usar una disposición personalizada podría ser la solución.

Sin embargo, hay una manera posible de mantener el widget appcompat , algunas pequeñas soluciones. En primer lugar, para evitar puhsing los otros elementos, puede utilizar el CollapseActionView .

 <item ... app:actionViewClass="android.support.v7.widget.SearchView" app:showAsAction="always|collapseActionView"/> 

Y para mantener sus requisitos, tiene que expandirlo cuando lo inicialice:

 final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item); MenuItemCompat.expandActionView(item); 

Tenga en cuenta que debe utilizar setOnActionExpandListener() para cerrar la ventana si no desea contraer el elemento. Esta sugerencia le dará este resultado:

Barra de herramientas con SearchView AppCompat expandido

Sin embargo, los márgenes adicionales, ¿verdad? Por lo tanto, usted tiene que recuperar el contenedor y el icono de abc_search_view.xml por sus ids (que se puede encontrar en abc_search_view.xml … pero vamos a ahorrar un tiempo: son R.id.search_edit_frame y R.id.search_mag_icon ). Puede eliminar sus márgenes utilizando este método:

 private void changeSearchViewElements(View view) { if (view == null) return; if (view.getId() == R.id.search_edit_frame || view.getId() == R.id.search_mag_icon) { LinearLayout.LayoutParams p = (LinearLayout.LayoutParams) view.getLayoutParams(); p.leftMargin = 0; // set no left margin view.setLayoutParams(p); } if (view instanceof ViewGroup) { ViewGroup viewGroup = (ViewGroup) view; for (int i = 0; i < viewGroup.getChildCount(); i++) { changeSearchViewElements(viewGroup.getChildAt(i)); } } } 

Llamándolo en un hilo:

 final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item); ... searchView.post(new Runnable() { @Override public void run() { changeSearchViewElements(searchView); } }); 

Aquí está la salida:

Barra de herramientas con SearchView AppCompat sin margen izquierdo

Finalmente, para obtener la línea bajo el campo, hay una solución posible como usar un 9-parche dibujable y establecerlo como un fondo. Puedes encontrar fácilmente cómo hacerlo en Google. Así que la condición será:

 private void changeSearchViewElements(View view) { ... if (view.getId() == R.id.search_edit_frame || view.getId() == R.id.search_mag_icon) { LinearLayout.LayoutParams p = (LinearLayout.LayoutParams) view.getLayoutParams(); p.leftMargin = 0; // set no left margin view.setLayoutParams(p); } else if (view.getId() == R.id.search_src_text) { AutoCompleteTextView searchEdit = (AutoCompleteTextView) view; searchEdit.setBackgroundResource(R.drawable.rect_underline_white); } ... } 

A partir del comentario del OP, el campo del subrayado también se puede hacer con la siguiente declaración:

 searchView.findViewById(android.support.v7.appcompat.R.id.se‌​arch_src_text) .setBa‌​ckgroundResource(R.d‌​rawable.abc_textfiel‌​d_search_default_mtr‌​l_alpha); 

Después de estas soluciones, como he dicho, podría ser más fácil utilizar un diseño personalizado. Pero si desea conservar el widget predeterminado de SearchView, esto podría ayudar.

  • Barra de Acción de Android SearchView Menu Icon Size
  • Android SearchView Ocultar el teclado al iniciar
  • Pasar la consulta de búsqueda ActionBar para fragmentar
  • Eliminar el relleno de Android SearchView cuando se amplía
  • ¿Cómo mover el icono de búsqueda de SearchView a la derecha?
  • Cambiar el texto de SearchView y el color de la sugerencia de appcompat
  • Mostrar icono de micrófono en SearchView siempre
  • SearchView fuente personalizada en android
  • No se puede obtener android.support.v7.widget.SearchView para aceptar el texto
  • Quitar icono de la vista de búsqueda del texto de la pista
  • El reemplazo de fragmentos activa onQueryTextChange en la vista de búsqueda
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.