J'ai de la difficulté à personnaliser l'icône de recherche dans SearchView. De mon point de vue, l'icône peut être modifiée dans les attributs de l'élément, non? Il suffit de vérifier le code ci-dessous ..
Est-ce que quelqu'un peut me dire ce que je fais mal?
C'est le menu que j'utilise, avec mon icône de recherche personnalisée icn_lupa . Mais quand je lance l'application, j'obtiens toujours l'icône de recherche par défaut ...
<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>
Merci d'avance.
Il semble que actionViewClass se trouve au-dessus de l’icône et il ne semble pas que vous puissiez le changer depuis cette classe .
Vous avez deux solutions:
J'ai trouvé un autre moyen de changer l'icône de recherche qui va dans le même sens que la réponse de Diego Pino mais directement dans onPrepareOptionsMenu
.
Dans votre menu.xml (comme avant)
<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>
Dans votre activité:
@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);
}
J'ai suivi l'exemple pour changer le edittext dans ce exemple .
Vous devriez pouvoir le faire pour tous les icônes/fonds de votre SearchView
. Pour trouver le bon ID, vous pouvez vérifier ici .
J'espère que cela aide aussi quelqu'un d'autre!
UPDATE Novembre 2017:
Depuis cette réponse, Android a été mis à jour avec la possibilité de changer l'icône de recherche via XML.
Si vous ciblez quelque chose sous Android v21, vous pouvez utiliser:
<Android.support.v7.widget.SearchView
Android:layout_width="wrap_content"
Android:layout_height="match_parent"
app:searchIcon="@drawable/ic_search_white_24dp"
app:closeIcon="@drawable/ic_clear_white_24dp" />
Ou v21 et plus tard:
<SearchView
Android:layout_width="wrap_content"
Android:layout_height="match_parent"
Android:searchIcon="@drawable/ic_search_white_24dp"
Android:closeIcon="@drawable/ic_clear_white_24dp" />
Et il y a encore plus d'options:
closeIcon
commitIcon
goIcon
searchHintIcon
searchIcon
voiceIcon
Belle réponse de @just_user
Pour mon cas, comme je me sers de la bibliothèque appcompat v7 pour le SearchView + ActionBar, j’ai un peu modifié sa solution pour la rendre compatible avec mon projet, elle devrait fonctionner si tant que vous n’avez rien modifié bibliothèque
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>
Code 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);
}
Excuse pour la très grande icône (je n’ai pas encore redimensionné l’icône), mais cela devrait fonctionner tel quel.
Je me débattais aussi avec ce problème, mais j’ai utilisé accidentellement 'collapseActionView' et cela a été corrigé! Mon menu.xml ressemble à ceci:
<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>
L'inconvénient est que, sur les tablettes, SearchView apparaîtra dans la partie gauche de la barre d'actions au lieu de l'emplacement où se trouve l'icône de recherche, mais cela ne me dérange pas.
J'ai défini un style pour le faire.
voici mon 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"/>
et c'est mon style:
<style name="CitySearchView" parent="Base.Widget.AppCompat.SearchView">
<item name="searchIcon">@drawable/ic_more_search</item>
</style>
Que c'est
Après avoir terminé, jetez simplement un coup d’œil à 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>
chaque élément peut être remplacé en définissant un nouveau style.
J'espère que ça aide!
Il y a un moyen de faire ça. L'astuce consiste à récupérer ImageView à l'aide de son identifiant et à définir une nouvelle image avec setImageResource()
. Cette solution est inspirée de Modification de l’arrière-plan dessinable du widget searchview .
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));
}
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) {
}
Après quelques recherches, j'ai trouvé la solution ici . Le truc, c'est que l'icône ne se trouve pas dans une ImageView
mais dans un objet 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);
<SearchView
Android:searchIcon="@drawable/ic_action_search"
..../>
utiliser la balise XML searchIcon
Astuce de mise à jour d'AutocompleteTextView pour la mise à jour de l'icône de recherche en mode développé, copiée à partir de la source 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);
}
De l'API 21, vous pouvez le changer en XML:
Android:searchIcon="@drawable/loupe"
Android:closeIcon="@drawable/x_white"
Dans le menu xml:
<item
Android:id="@+id/menu_filter"
Android:actionLayout="@layout/menu_filter"
Android:icon="@drawable/ic_menu_filter"
Android:orderInCategory="10"
Android:showAsAction="always"
Android:title="@string/menu_filter"/>
et créez le layout/menu_filter
:
<?xml version="1.0" encoding="utf-8"?>
<SearchView
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:searchIcon="@drawable/ic_menu_filter"/>
alors dans l'activité onCreateOptionsMenu
ou onPrepareOptionsMenu
:
SearchView searchView = (SearchView) menu.findItem(R.id.menu_filter).getActionView();
searchView.setOnQueryTextListener(this);
pour le niveau d'api <21, j'ai fait ceci:
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 cette
pour ça
Il y a trois icônes en forme de loupe. deux d'entre eux sont affichés lorsque IconizedByDefault est true (un qui est affiché avant d'appuyer et un est indiqué dans le "conseil") et un est affiché tout le temps quand IconizedByDefault est false. Comme tous les champs sont privés, vous devez les obtenir par leur identifiant XML. (la plupart du code est déjà mentionné séparément dans d'autres réponses de cet article)
lorsque IconizedByDefault est défini sur true, modifiez l'icône dans l'indicateur (visible uniquement après avoir appuyé sur l'icône) en:
mSearchSrcTextView = (SearchAutoComplete)findViewById(R.id.search_src_text);
puis faites la même chose que dans le code source 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 a été remplacé par newSearchIconDrawable, qui est votre nouvelle icône de recherche. Ensuite, réglez l'indice avec
mSearchSrcTextView.setHint(ssb);
Les 2 autres icônes sont dans une ImageView
, qui peut être trouvée par leur ID . Pour l'icône lorsque searchview est fermé (lorsque iconizedByDefault est true):
mSearchButton = (ImageView) findViewById(R.id.search_button);
et pour celui qui apparaît toujours (si iconizedByDefault est false)
mCollapsedIcon = (ImageView) findViewById(R.id.search_mag_icon);
Une solution désespérée avec Kotlin
val s = (searchView.getAllChildren().firstOrNull() as? LinearLayout)?.getAllChildren()?.filter { it is AppCompatImageView }?.firstOrNull() as? AppCompatImageView
s?.setImageResource(R.drawable.search)
getAllChildren:
fun ViewGroup.getAllChildren() : ArrayList<View> {
val views = ArrayList<View>()
for (i in 0..(childCount-1)) {
views.add(getChildAt(i))
}
return views
}
J'espère que ça aide quelqu'un.
Nommez simplement votre icône du même nom que l’icône utilisée par la vue de recherche. Lors de la compilation, la ressource du projet est placée sur l'icône de la bibliothèque.
Ma solution: Utiliser deux fichiers XML de menu. Dans l’un des xml, l’élément de menu a une actionView et dans l’autre non. Gonflez d'abord le menu réduit et, lorsque vous cliquez sur l'élément de menu, invalidez le menu et gonflez le menu développé xml et assurez-vous d'appeler 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);
}