Как изменить значок по умолчанию на 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>


спасибо заранее.

897   18  

18 ответов:

похоже, что 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);
}

извините за очень большой значок (Я еще не изменил размер значка), но он должен работать так, как он есть.

enter image description here

Я тоже боролся с этим, но потом я случайно использовал "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"
<SearchView
            android:searchIcon="@drawable/ic_action_search"
..../>

используйте xml-тег searchIcon

для уровня 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);

от этого

enter image description here

этой

enter image description here

есть три значка увеличительного стекла. два из них отображаются, когда 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

    Ничего не найдено.