如何更改SearchView上的默认图标,以在Android上的操作栏中使用?

我在自定义SearchView中的search图标时遇到了一些麻烦。 在我看来,图标可以在Item属性中更改,对吧? 只要检查下面的代码

有人能告诉我我做错了什么吗?

这是我正在使用的菜单,我的自定义search图标icn_lupa 。 但是,当我运行的应用程序,我总是得到默认的search图标…

<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> 

提前致谢。

它看起来像actionViewClass覆盖图标,它看起来不像你可以改变它从这个类 。

你有两个解决scheme:

  • 与它一起生活,我认为这是用户体验和平台一致性方面的最佳select。
  • 定义你自己的actionViewClass

我find了另一种方法来改变search图标,在迭onPrepareOptionsMenu的回答,但在onPrepareOptionsMenu

在你的menu.xml中(和以前一样)

 <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> 

在你的活动中:

 @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); } 

在这个例子中,我跟着这个例子改变了edittext。

您应该能够在SearchView为所有图标/背景执行此操作,以查找您可以在此处 SearchView的正确ID。

希望这可以帮助别人!

来自@just_user的好回答

对于我来说,因为我正在使用SearchView + ActionBar的appcompat v7库,所以我修改了他的解决scheme,使其与我的项目兼容,它应该工作,只要你没有修改任何东西,当你添加appcompat v7图书馆

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> 

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); } 

对于这个非常大的图标(我还没有调整图标大小),不过应该照原样运行。

在这里输入图像描述

我也在为此苦苦挣扎,但后来我意外地使用了“collapseActionView”,并修复了它! 我的menu.xml如下所示:

 <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> 

不足之处在于,在平板电脑上,SearchView将显示在ActionBar的左侧,而不是searchicon的位置,但我不介意。

有一种方法可以做到这一点。 诀窍是使用其标识符恢复ImageView,并使用setImageResource()设置新的图像。 这个解决scheme的启发是改变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)); } 

我定义了一个风格来做到这一点。

这里是我的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"/> 

这是我的风格:

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

那个!

完成后,只需看看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> 

每个项目都可以通过定义一个新的样式来覆盖。

希望它有帮助!

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) { } 

经过一番研究,我在这里find了解决办法 诀窍是该图标不在ImageView而是在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); 

更新提示的AutocompleteTextView更新search图标在扩展模式下,从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); } 

从API 21,你可以改变它在XML:

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

使用searchIcon xml标签

对于api级别<21,我做了这个:

  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); 

由此

在这里输入图像描述

对此

在这里输入图像描述

有三个放大镜图标。 当IconizedByDefault为真(在按下之前显示一个,在“提示”中显示一个)时显示它们中的两个,并且在IconizedByDefault为假时始终显示一个。 所有的领域是私人的,所以得到他们的方式是由他们的XML ID。 (大部分代码已经在这篇文章的其他答案中分别提到)

当IconizedByDefault为true时,通过以下方式更改提示中的图标(仅在按下图标后才能看到):

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

然后在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被newSearchIconDrawablereplace,这是您的新search图标。 然后设置提示

 mSearchSrcTextView.setHint(ssb); 

其他2个图标在ImageView ,可以通过它们的Idfind。 对于searchviewclosures时的图标(当iconizedByDefault为true时):

 mSearchButton = (ImageView) findViewById(R.id.search_button); 

和总是出现的那个(如果iconizedByDefault是假的)

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

我的解决scheme:使用两个菜单的XML文件。 在其中一个xml中,菜单项有一个actionView,另一个没有。 最初膨胀折叠的菜单,当菜单项被点击时,使菜单无效并膨胀展开的菜单xml,并确保调用了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); } 

只需将您的图标命名为search视图使用的图标。 编译时,将项目中的资源占用库中的图标。

我使用AppCompat库。 是的,指定android:icon="@drawable/search_icon_png"不起作用。 所以我查看了@ style / Theme.AppCompat的源代码,并find了android使用的图标。

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

因此,如果您将abc_ic_search.png内的search图标重命名为abc_ic_search.png ,则此图标将呈现为您的应用程序中的可绘制图标,而不是appcompat可绘制文件夹。 适用于我:)

使用这种方法,您还可以自定义search小部件的closures和清除图标。