Как изменить значок по умолчанию на SearchView, чтобы использовать в панели действий на Android?
У меня возникли некоторые проблемы с настройкой значка поиска в SearchView. На мой взгляд, значок можно изменить в атрибутах элемента, верно? Просто проверьте код ниже..
может кто подскажет, что я делаю неправильно?
это меню, которое я использую, с моим пользовательским значком поиска icn_lupa. Но когда я запускаю приложение, я всегда получаю значок поиска по умолчанию...
<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>
спасибо заранее.
18 ответов:
похоже, что actionViewClass перекрывает значок, и не похоже, что вы можете изменить его с этот класс.
У вас есть два решения:
- жить с ним, и я думаю, что это лучший вариант с точки зрения пользовательского опыта и соответствия платформы.
- определите свой собственный actionViewClass
Я нашел другой способ изменить значок поиска, который идет в той же строке, что и ответ Диего Пино, но прямо в
onPrepareOptionsMenu.в вашем меню.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, чтобы найти правильный идентификатор, который вы можете проверить здесь.надеюсь, что это поможет кому-то еще, а также!
обновление ноябрь 2017:
так как этот ответ android был обновлен с возможностью изменения значка поиска через XML.
если вы нацелены на что-нибудь ниже android v21 вы можете использовать:
<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" />или v21 и позже:
<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" />и есть еще варианты:
closeIcon commitIcon goIcon searchHintIcon searchIcon voiceIcon
хороший ответ от @just_user
в моем случае, поскольку я использую библиотеку appcompat v7 для SearchView + ActionBar, я немного изменил его решение, чтобы сделать его совместимым с моим проектом, он должен работать до тех пор, пока вы ничего не изменили при добавлении 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", и это исправило его! Мое меню.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 появится в левой части панели действий вместо того, где находится searchicon, но я не возражаю против этого.
Я определил стиль, чтобы сделать это .
вот мой 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>что он!
после завершения этого, просто взгляните на базу.Штучка.Совместимости приложений.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>каждый элемент может быть переопределен путем определения нового стиля .
надеюсь, что это помогает!
есть способ сделать это. Хитрость заключается в том, чтобы восстановить ImageView, используя его идентификатор и установив новое изображение с
setImageResource(). Это решение вдохновлено на изменение фона drawable виджета 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) { }
после некоторых исследований я нашел решение здесь. Фокус в том, что значок не находится в
ImageViewа в
обновить подсказку AutocompleteTextView для обновления значка поиска в расширенном режиме, скопированного из источника 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"
для уровня api
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 является true(один, который отображается перед нажатием и один отображается в "подсказке"), и один отображается все время, когда IconizedByDefault является false. все поля являются частными, поэтому способ их получения - это их xml-идентификатор. (большая часть кода упоминается отдельно в других ответах в этом посте уже)
когда 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 был заменен на newSearchIconDrawable, который является вашим новым значком поиска. Затем установите подсказку с
mSearchSrcTextView.setHint(ssb);остальные 2 иконки находятся в
ImageView, который можно найти по их Id. для значка при закрытии searchview (когда iconizedByDefault имеет значение true) выполните:mSearchButton = (ImageView) findViewById(R.id.search_button);и для того, который всегда появляется (если iconizedByDefault ложь)
mCollapsedIcon = (ImageView) findViewById(R.id.search_mag_icon);
в меню 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"/>создать
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"/>тогда в деятельности
onCreateOptionsMenuилиonPrepareOptionsMenu:SearchView searchView = (SearchView) menu.findItem(R.id.menu_filter).getActionView(); searchView.setOnQueryTextListener(this);
мое решение: Используйте два XML-файла меню. В одном из xmls пункт меню имеет 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); }
просто назовите свой значок тем же именем, что и значок, который используется в представлении поиска. Когда он компилируется, он берет ресурс в проекте над значком в библиотеке.
отчаянное решение с помощью 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 }надеюсь, что это поможет кому-то.
Я использую библиотеку AppCompat. Да, указав
android:icon="@drawable/search_icon_png"не работает. Поэтому я заглянул в исходный код @style/Theme.AppCompat и нашел значок, который использует android.<item name="searchViewSearchIcon">@drawable/abc_ic_search</item>поэтому, если вы переименуете значок поиска внутри своих чертежей в
abc_ic_search.png, этот значок отображается как найденный в вашем приложении drawable first, а не в папке AppCompat drawable. Работает для меня:)С помощью этого подхода вы можете настроить закрыть и очистить значки для виджета поиска как что ж.



Comments