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.
- El relleno de espacio vacío es demasiado grande.
- No quiero ocultar otras acciones, pero estas acciones se superponen con SearchView.
- El subrayado de SearchView no está visible
¿Cómo puedo solucionar los problemas mencionados anteriormente?
- Buscar sugerencias de diferentes tablas en diferentes actividades
- Buscar EditarTexto de animación como la aplicación de Chrome
- Android ActionBar: plegable SearchView con botón de acción
- Android: haga que la barra de búsqueda completa pueda hacer clic
- No se puede llamar a void android.view.View.setElevation (float) en un objeto nulo en lapism / SearchView
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(); } }); }
- Ejemplo de android.support.v4.widget.SearchViewCompat?
- Crear ContentProvider asincrónico para Actionbar SearchView
- NullPointerException en SearchView con ActionBarSherlock
- Barra de acción con la vista de búsqueda. Problemas de compatibilidad inversa
- La entrada de texto en SearchView no se muestra
- Widget SearchView no aparece en la barra de acciones
- Android SDK 22 - Problemas de representación de SearchView
- Android - NullPointerException en SearchView en la barra de acciones
Con respecto a su código publicado, este es el resultado:
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:
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:
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.search_src_text) .setBackgroundResource(R.drawable.abc_textfield_search_default_mtrl_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.