Cómo cambiar el icono predeterminado en el SearchView, para ser utilizado en la barra de acción de Android?

Tengo problemas para personalizar el icono de búsqueda en el SearchView. En mi punto de vista, el icono se puede cambiar en los atributos del artículo, ¿verdad? Sólo marca el código abajo.

¿Puede alguien decirme lo que estoy haciendo mal?

Este es el menú que estoy usando, con mi icono de búsqueda personalizado icn_lupa . Pero cuando ejecuto la aplicación, siempre obtengo el icono de búsqueda predeterminado …

<menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/menu_search" android:title="@string/menu_search" android:icon="@drawable/icn_lupa" android:showAsAction="always" android:actionViewClass="android.widget.SearchView" /> </menu> 

Gracias por adelantado.

Parece que el actionViewClass supera el icono y no parece que puede cambiarlo de esta clase .

Tienes dos soluciones:

  • Vivir con ella y creo que es la mejor opción en términos de la experiencia del usuario y la conformidad de la plataforma.
  • Defina su propia actionViewClass

He encontrado otra manera de cambiar el icono de búsqueda que va en la misma línea que la respuesta de Diego Pino, pero directamente en onPrepareOptionsMenu .

En su menu.xml (igual que antes)

 <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/action_search" android:icon="@drawable/ic_action_fav" android:title="@string/action_websearch" android:showAsAction="always|never" android:actionViewClass="android.widget.SearchView" /> </menu> 

En su actividad:

 @Override public boolean onPrepareOptionsMenu(Menu menu) { MenuItem searchViewMenuItem = menu.findItem(R.id.action_search); mSearchView = (SearchView) searchViewMenuItem.getActionView(); int searchImgId = getResources().getIdentifier("android:id/search_button", null, null); ImageView v = (ImageView) mSearchView.findViewById(searchImgId); v.setImageResource(R.drawable.your_new_icon); mSearchView.setOnQueryTextListener(this); return super.onPrepareOptionsMenu(menu); } 

He seguido el ejemplo para cambiar el edittext en este ejemplo .

Debe ser capaz de hacer esto para todos los iconos / fondos en su SearchView , para encontrar el ID correcto que puede comprobar aquí .

Espero que esto ayude a otra persona también!

Buena respuesta de @just_user

Para mi caso, ya que estoy usando la librería appcompat v7 para el SearchView + ActionBar, he modificado su solución un poco para que sea compatible con mi proyecto, debería funcionar siempre y cuando no se haya modificado nada al agregar appcompat v7 como biblioteca

XML:

 <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:metrodeal="http://schemas.android.com/apk/res-auto" > <item android:id="@+id/main_menu_action_search" android:orderInCategory="100" android:title="@string/search" metrodeal:showAsAction="always" metrodeal:actionViewClass="android.support.v7.widget.SearchView" android:icon="@drawable/search_btn"/> </menu> 

Código Java:

 @Override public void onPrepareOptionsMenu(Menu menu) { MenuItem searchViewMenuItem = menu.findItem(R.id.main_menu_action_search); SearchView mSearchView = (SearchView) MenuItemCompat.getActionView(searchViewMenuItem); int searchImgId = android.support.v7.appcompat.R.id.search_button; // I used the explicit layout ID of searchview's ImageView ImageView v = (ImageView) mSearchView.findViewById(searchImgId); v.setImageResource(R.drawable.search_btn); super.onPrepareOptionsMenu(menu); } 

Disculpa por el ícono muy grande (todavía no he cambiado el tamaño del icono), pero debería funcionar como está.

Introduzca aquí la descripción de la imagen

Yo estaba luchando con esto también, pero luego accidentalmente utilizado 'collapseActionView' y que lo arregló! Mi menu.xml se parece a esto ahora:

 <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/menu_search" android:title="@string/menu_search" android:showAsAction="always|withText|collapseActionView" android:actionViewClass="android.widget.SearchView" android:icon="@android:drawable/ic_menu_search" /> </menu> 

La desventaja de esto es que en las tabletas el SearchView aparecerá en el lado izquierdo de la ActionBar en lugar de donde está el searchicon, pero no me importa eso.

Hay una manera de hacer esto. El truco es recuperar el ImageView con su identificador y establecer una nueva imagen con setImageResource() . Esta solución se inspira en Cambiar el fondo dibujable del widget de búsqueda .

 private SearchView searchbox; private void customizeSearchbox() { setSearchHintIcon(R.drawable.new_search_icon); } private void setSearchHintIcon(int resourceId) { ImageView searchHintIcon = (ImageView) findViewById(searchbox, "android:id/search_mag_icon"); searchHintIcon.setImageResource(resourceId); } private View findViewById(View v, String id) { return v.findViewById(v.getContext().getResources(). getIdentifier(id, null, null)); } 

Definí un estilo para hacerlo.

Aquí está mi xml:

  <android.support.v7.widget.SearchView android:id="@+id/sv_search" android:icon="@android:drawable/ic_menu_search" android:layout_width="fill_parent" **style="@style/CitySearchView"** android:layout_height="wrap_content"/> 

Y este es mi estilo:

 <style name="CitySearchView" parent="Base.Widget.AppCompat.SearchView"> <item name="searchIcon">@drawable/ic_more_search</item> </style> 

¡Eso sí!

Después de terminar, sólo echar un vistazo a Base.Widget.AppCompat.SearchView.

 <style name="Base.Widget.AppCompat.SearchView" parent="android:Widget"> <item name="layout">@layout/abc_search_view</item> <item name="queryBackground">@drawable/abc_textfield_search_material</item> <item name="submitBackground">@drawable/abc_textfield_search_material</item> <item name="closeIcon">@drawable/abc_ic_clear_mtrl_alpha</item> <item name="searchIcon">@drawable/abc_ic_search_api_mtrl_alpha</item> <item name="goIcon">@drawable/abc_ic_go_search_api_mtrl_alpha</item> <item name="voiceIcon">@drawable/abc_ic_voice_search_api_mtrl_alpha</item> <item name="commitIcon">@drawable/abc_ic_commit_search_api_mtrl_alpha</item> <item name="suggestionRowLayout">@layout/abc_search_dropdown_item_icons_2line</item> </style> 

Cada elemento puede ser reemplazado por definir un nuevo estilo.

¡Espero eso ayude!

SearchView searchView = (SearchView) findViewById (R.id.address_search);

  try { Field searchField = SearchView.class .getDeclaredField("mSearchButton"); searchField.setAccessible(true); ImageView searchBtn = (ImageView) searchField.get(searchView); searchBtn.setImageResource(R.drawable.search_glass); } catch (NoSuchFieldException e) { } catch (IllegalAccessException e) { } 

Después de algunas investigaciones encontré la solución aquí . El truco es que el icono no está en un ImageView sino en el objeto Spannable .

 // Accessing the SearchAutoComplete int queryTextViewId = getResources().getIdentifier("android:id/search_src_text", null, null); View autoComplete = searchView.findViewById(queryTextViewId); Class<?> clazz = Class.forName("android.widget.SearchView$SearchAutoComplete"); SpannableStringBuilder stopHint = new SpannableStringBuilder(" "); stopHint.append(getString(R.string.your_new_text)); // Add the icon as an spannable Drawable searchIcon = getResources().getDrawable(R.drawable.ic_action_search); Method textSizeMethod = clazz.getMethod("getTextSize"); Float rawTextSize = (Float)textSizeMethod.invoke(autoComplete); int textSize = (int) (rawTextSize * 1.25); searchIcon.setBounds(0, 0, textSize, textSize); stopHint.setSpan(new ImageSpan(searchIcon), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // Set the new hint text Method setHintMethod = clazz.getMethod("setHint", CharSequence.class); setHintMethod.invoke(autoComplete, stopHint); 

Sugerencia de actualización de AutocompleteTextView para actualizar el icono de búsqueda en el modo expandido, copiado de la fuente de Android,

 @Override public boolean onPrepareOptionsMenu(Menu menu) { mSearchMenuItem = menu.findItem(R.id.action_search); SearchView searchView = (SearchView) mSearchMenuItem.getActionView(); int searchImgId = getResources().getIdentifier("android:id/search_button", null, null); ImageView v = (ImageView) searchView.findViewById(searchImgId); v.setImageResource(R.drawable.search_or); int searchTextViewId = searchView.getContext().getResources().getIdentifier("android:id/search_src_text", null, null); AutoCompleteTextView searchTextView = (AutoCompleteTextView) searchView.findViewById(searchTextViewId); searchTextView.setHintTextColor(getResources().getColor(R.color.hint_color_white)); searchTextView.setTextColor(getResources().getColor(android.R.color.white)); searchTextView.setTextSize(18.0f); SpannableStringBuilder ssb = new SpannableStringBuilder(" "); // for the icon ssb.append(hintText); Drawable searchIcon = getResources().getDrawable(R.drawable.search_or); int textSize = (int) (searchTextView.getTextSize() * 1.25); searchIcon.setBounds(0, 0, textSize, textSize); ssb.setSpan(new ImageSpan(searchIcon), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); searchTextView.setHint(ssb); return super.onPrepareOptionsMenu(menu); } 

Desde API 21 puede cambiarlo en xml:

 android:searchIcon="@drawable/loupe" android:closeIcon="@drawable/x_white" 
 <SearchView android:searchIcon="@drawable/ic_action_search" ..../> 

Utilice la etiqueta searchIcon xml

Para api nivel <21, hice esto:

  int searchImgId = getResources().getIdentifier("android:id/search_mag_icon", null, null); ImageView ivIcon = (ImageView) searchView.findViewById(searchImgId); if(ivIcon!=null) ivIcon.setImageResource(R.drawable.ic_search); 

de esto

Introduzca aquí la descripción de la imagen

a esto

Introduzca aquí la descripción de la imagen

Hay tres iconos de lupa. Dos de ellos se muestran cuando IconizedByDefault es true (uno que se muestra antes de presionar y uno se muestra en la "pista") y uno se muestra todo el tiempo cuando IconizedByDefault es falso. Todos los campos son privados así que la manera de conseguirlos está por su identificación del xml. (La mayor parte del código se menciona por separado en otras respuestas en este post ya)

Cuando IconizedByDefault es true, cambia el icono en la pista (que se ve sólo después de presionar el icono) mediante:

 mSearchSrcTextView = (SearchAutoComplete)findViewById(R.id.search_src_text); 

A continuación, haga lo mismo que en el código fuente de Android:

 final int textSize = (int) (mSearchSrcTextView.getTextSize() * 1.25); newSearchIconDrawable.setBounds(0, 0, textSize, textSize); final SpannableStringBuilder ssb = new SpannableStringBuilder(" "); ssb.setSpan(new ImageSpan(newSearchIconDrawable), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); ssb.append(hintText); 

MSearchHintIcon fue reemplazado por newSearchIconDrawable que es su nuevo icono de búsqueda. A continuación, establezca la sugerencia con

 mSearchSrcTextView.setHint(ssb); 

Los otros 2 iconos se encuentran en una vista de imagen que se puede encontrar por allí Id. Para el icono cuando se cierra searchview do (cuando iconizedByDefault es true) mSearchButton = (ImageView) findViewById (R.id.search_button); Y para el que siempre aparece (si iconizedByDefault es false)

 mCollapsedIcon = (ImageView) findViewById(R.id.search_mag_icon); 

Mi solución: Utilice dos archivos xml de menú. En uno de los xmls el elemento de menú tiene una actionView y en el otro no. Inicialmente infle el menú colapsado y cuando se hace clic en el elemento del menú, invalida el menú e infla el xml del menú expandido y asegúrate de llamar a setIconified (false);

 @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { if(!mShowSearchView) { inflater.inflate(R.menu.menu_collapsed, menu); } else { inflater.inflate(R.menu.menu_expanded, menu); MenuItem searchItem = menu.findItem(R.id.action_search); SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem); searchView.setIconified(false); searchView.setOnCloseListener(new OnCloseListener() { @Override public boolean onClose() { mShowSearchView = false; ActivityCompat.invalidateOptionsMenu(getActivity()); return false; } }); } super.onCreateOptionsMenu(menu, inflater); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.action_filter) { menu.showMenu(); } else if (item.getItemId() == R.id.action_search) { mShowSearchView = true; ActivityCompat.invalidateOptionsMenu(getActivity()); } return super.onOptionsItemSelected(item); } 

Simplemente nombre su icono con el mismo nombre que el icono que utiliza la vista de búsqueda. Cuando compila toma el recurso en el proyecto sobre el icono en la biblioteca.

Yo uso la librería AppCompat. Sí, especificando android:icon="@drawable/search_icon_png" no funciona. Así que miré en el código fuente de @ style / Theme.AppCompat y encontré el icono que usa android.

 <item name="searchViewSearchIcon">@drawable/abc_ic_search</item> 

Por lo tanto, si cambia el nombre de su icono de búsqueda dentro de los abc_ic_search.png a abc_ic_search.png , este ícono se representa como el que se encuentra en su aplicación primero, en lugar de la carpeta dibujable appcompat. Funciona para mi 🙂

Utilizando este enfoque, puede personalizar los iconos cercanos y claros para el widget de búsqueda.

  • Android acción barra título elipsis
  • El botón de retroceso de la barra de acción no se va a volver en Android
  • Título de barra de acción con más de una línea?
  • Barra de Acción de Android cambia la posición de los menús
  • El icono de la aplicación no aparece en la barra de acciones de Android
  • Cómo cambiar el color de la pestaña seleccionada
  • Diferente aspecto / estilo para el elemento de menú específico en ActionBar
  • Lengüetas de la barra de la acción de Android
  • La navegación ActionBar up recrea la actividad principal en lugar de onResume
  • Holo Light con Dark Actionbar muestra Holo Dark copiar y pegar iconos
  • Cómo cambiar el texto en la barra de acción
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.