Alterando o drawable em segundo plano do widget searchview

122

Estou tentando alterar o desenho que fica no widget da barra de ação da barra de ação do Android.

Atualmente, é assim: insira a descrição da imagem aqui

mas preciso alterar o plano de fundo azul desenhável para uma cor vermelha.

Eu tentei muitas coisas antes de rolar meu próprio widget de pesquisa, mas nada parece funcionar.

Alguém pode me indicar a direção certa para mudar isso?

Martyn
fonte
1
Acredito que este post SO possa ajudá-lo com o que você deseja realizar, se você ainda não o tiver verificado.
Angelo
@ Angelo Infelizmente, isso não é possível em SearchViewsegundo plano porque não está disponível no meio R.styleable. Minha resposta abaixo descreve como fazer isso no código.
vArDo 13/08/12
Como você recebeu o texto "Digite o nome do filme"?
Zen
Você pode definir o texto da dica na exibição de pesquisa assim: SearchView.SearchAutoComplete searchAutoComplete = (SearchView.SearchAutoComplete) searchView.findViewById (android.support.v7.appcompat.R.id.search_src_text); searchAutoComplete.setHint ("texto da dica");
Dominik

Respostas:

253

Introdução

Infelizmente, não há como definir o SearchViewestilo do campo de texto usando temas, estilos e herança em XML, como você pode fazer com o segundo plano dos itens no menu suspenso ActionBar . Isto é porque selectableItemBackground é listado como styleable em R.stylable, ao passo que searchViewTextField(atributo tema que estamos interessados em) não é. Portanto, não podemos acessá-lo facilmente a partir de recursos XML (você receberá um No resource found that matches the given name: attr 'android:searchViewTextField'erro).

Configurando o SearchView segundo plano do campo de texto a partir do código

Portanto, a única maneira de substituir adequadamente o plano de fundo do SearchViewcampo de texto é acessá-lo internamente, obter acesso à visualização que possui o plano de fundo com base searchViewTextFielde definir o nosso.

OBSERVAÇÃO: A solução abaixo depende apenas da id ( android:id/search_plate) do elemento SearchView, portanto, é mais independente da versão SDK do que a passagem das crianças (por exemplo, usar searchView.getChildAt(0)para obter a visão correta dentro SearchView), mas não é à prova de balas. Especialmente se algum fabricante decidir reimplementar SearchViewelementos internos e o ID acima mencionado não estiver presente - o código não funcionará.

No SDK, o plano de fundo do campo de texto SearchViewé declarado através de nove patches ; portanto, faremos da mesma maneira. Você pode encontrar imagens png originais no diretório drawable-mdpi do repositório git do Android . Estamos interessados ​​em duas imagens. Um para o estado em que o campo de texto está selecionado (denominado textfield_search_selected_holo_light.9.png ) e outro para onde não está (chamado textfield_search_default_holo_light.9.png ).

Infelizmente, você precisará criar cópias locais das duas imagens, mesmo se desejar personalizar apenas o estado focado . Isso ocorre porque textfield_search_default_holo_lightnão está presente no R..drawable . Portanto, não é de fácil acesso @android:drawable/textfield_search_default_holo_light, o que poderia ser usado no seletor mostrado abaixo, em vez de fazer referência ao drawable local.

NOTA: Eu estava usando o tema Holo Light como base, mas você pode fazer o mesmo com o Holo Dark . Parece que não há diferença real nos 9 patches selecionados do estado entre os temas Claro e Escuro . No entanto, há uma diferença nos 9 patches para o estado padrão (consulte Claro vs Escuro ). Portanto, provavelmente não há necessidade de fazer cópias locais de 9 patches para o estado selecionado , para os temas Escuro e Claro (supondo que você queira lidar com ambos e fazer com que ambos pareçam os mesmos do Tema Holo ). Basta fazer uma cópia local e usá-la emselecionável para os dois temas.

Agora, você precisará editar nove patches baixados conforme sua necessidade (por exemplo, alterando a cor azul para vermelha). Você pode dar uma olhada no arquivo usando a ferramenta draw 9-patch para verificar se ele está definido corretamente após a sua edição.

Editei arquivos usando o GIMP com a ferramenta lápis de um pixel (bastante fácil), mas você provavelmente usará a ferramenta por conta própria. Aqui está o meu patch 9 personalizado para o estado focado :

insira a descrição da imagem aqui

NOTA: Para simplificar, usei apenas imagens para densidade mdpi . Você precisará criar 9 patches para várias densidades de tela se desejar o melhor resultado em qualquer dispositivo. As imagens para Holo SearchView podem ser encontradas nos mdpi , hdpi e xhdpi drawable.

Agora, precisamos criar um seletor desenhável, para que a imagem apropriada seja exibida com base no estado da visualização. Crie um arquivo res/drawable/texfield_searchview_holo_light.xmlcom o seguinte conteúdo:

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true"
        android:drawable="@drawable/textfield_search_selected_holo_light" />
    <item android:drawable="@drawable/textfield_search_default_holo_light" />
</selector>

Usaremos o drawable criado acima para definir o plano de fundo da LinearLayoutvisualização que contém o campo de texto SearchView- seu ID é android:id/search_plate. Então, veja como fazer isso rapidamente no código, ao criar o menu de opções:

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }       

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);

        // Getting SearchView from XML layout by id defined there - my_search_view in this case
        SearchView searchView = (SearchView) menu.findItem(R.id.my_search_view).getActionView();
        // Getting id for 'search_plate' - the id is part of generate R file,
        // so we have to get id on runtime.
        int searchPlateId = searchView.getContext().getResources().getIdentifier("android:id/search_plate", null, null);
        // Getting the 'search_plate' LinearLayout.
        View searchPlate = searchView.findViewById(searchPlateId);
        // Setting background of 'search_plate' to earlier defined drawable.            
        searchPlate.setBackgroundResource(R.drawable.textfield_searchview_holo_light);          

        return super.onCreateOptionsMenu(menu);
    }

}

Efeito final

Aqui está a captura de tela do resultado final:

insira a descrição da imagem aqui

Como cheguei a isso

Acho que vale a pena mencionar como cheguei a isso, para que essa abordagem possa ser usada ao personalizar outras visualizações.

Verificando o layout da vista

Eu verifiquei como é o SearchViewlayout. No contratador do SearchView, é possível encontrar uma linha que infla o layout:

inflater.inflate(R.layout.search_view, this, true);

Agora sabemos que o SearchViewlayout está no arquivo nomeado res/layout/search_view.xml. Olhando para search_view.xml , podemos encontrar um LinearLayoutelemento interno (com ID search_plate) que contém android.widget.SearchView$SearchAutoComplete(parece com o nosso campo de texto de exibição de pesquisa):

    <LinearLayout
        android:id="@+id/search_plate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:layout_gravity="center_vertical"
        android:orientation="horizontal"
        android:background="?android:attr/searchViewTextField">

Agora, agora que o plano de fundo está definido com base no searchViewTextFieldatributo do tema atual .

Atributo de investigação (é facilmente configurável?)

Para verificar como o searchViewTextFieldatributo é definido, investigamos res / values ​​/ themes.xml . Há um grupo de atributos relacionados ao SearchViewpadrão Theme:

<style name="Theme">
    <!-- (...other attributes present here...) -->

    <!-- SearchView attributes -->
    <item name="searchDropdownBackground">@android:drawable/spinner_dropdown_background</item>
    <item name="searchViewTextField">@drawable/textfield_searchview_holo_dark</item>
    <item name="searchViewTextFieldRight">@drawable/textfield_searchview_right_holo_dark</item>
    <item name="searchViewCloseIcon">@android:drawable/ic_clear</item>
    <item name="searchViewSearchIcon">@android:drawable/ic_search</item>
    <item name="searchViewGoIcon">@android:drawable/ic_go</item>
    <item name="searchViewVoiceIcon">@android:drawable/ic_voice_search</item>
    <item name="searchViewEditQuery">@android:drawable/ic_commit_search_api_holo_dark</item>
    <item name="searchViewEditQueryBackground">?attr/selectableItemBackground</item>

Vemos que para o tema padrão, o valor é @drawable/textfield_searchview_holo_dark. Para Theme.Lightvalor também é definido nesse arquivo .

Agora, seria ótimo se esse atributo estivesse acessível através do R.styleable , mas, infelizmente, não é. Para comparação, consulte outros atributos do tema que estão presentes em themes.xml e R.attr, como textAppearance ou selectableItemBackground . Se searchViewTextFieldestivesse presente em R.attr(e R.stylable), poderíamos simplesmente usar nosso seletor de desenho ao definir o tema para todo o aplicativo em XML. Por exemplo:

<resources xmlns:android="http://schemas.android.com/apk/res/android">

    <style name="AppTheme" parent="android:Theme.Light">
        <item name="android:searchViewTextField">@drawable/textfield_searchview_holo_light</item>
    </style>
</resources>

O que deve ser modificado?

Agora sabemos que teremos que acessar search_plateatravés do código. No entanto, ainda não sabemos como deve ser. Em resumo, procuramos por elementos de desenho usados ​​como valores em temas padrão: textfield_searchview_holo_dark.xml e textfield_searchview_holo_light.xml . Analisando o conteúdo, vemos que o drawable é o selectorque faz referência a outros dois drawables (que ocorrem com 9 patches posteriormente) com base no estado da visualização. Você pode encontrar drawables agregados de 9 patches em (quase) todas as versões do Android em androiddrawables.com

Customizando

Reconhecemos a linha azul em um dos 9 patches , então criamos uma cópia local e alteramos as cores conforme desejado.

vArDo
fonte
Seu código java não funcionará, o SearchView dele está na ActionBar e não pode ser encontrado com o método findViewById. Mas o resto está correto!
22812 VinceFR
@VinceFR Obrigado por apontar isso. Não percebi (eu me concentrei em SearchViewsi mesmo). Tudo bem se eu mesclar sua resposta (substituindo onCreateOptionsMenu) na minha?
vArDo 26/07/12
@VinceFR Mudei meu código de onCreate()método para onCreateOptionsMenu()método, como você sugeriu. Votou sua resposta.
vArDo 26/07/12
Muito obrigado: D existe alguma maneira de alterar o ícone Mag e o ícone Fechar de maneira semelhante?
Harsha MV
Como podemos alterar um ícone de lupa? Eu tento de tudo, mas não consigo mudar ... Obrigado ... e como fazer isso na barra de ação do sherlock?
Jovan
31

As soluções acima podem não funcionar se você estiver usando a biblioteca appcompat. Pode ser necessário modificar o código para fazê-lo funcionar na biblioteca appcompat.

Aqui está a solução de trabalho para a biblioteca appcompat.

  @Override
  public boolean onCreateOptionsMenu(Menu menu)
  {

    getMenuInflater().inflate(R.menu.main_menu, menu); 

    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    MenuItem searchMenuItem = menu.findItem(R.id.action_search);
    SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem);
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));

    SearchView.SearchAutoComplete searchAutoComplete = (SearchView.SearchAutoComplete)searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
    searchAutoComplete.setHintTextColor(Color.WHITE);
    searchAutoComplete.setTextColor(Color.WHITE);

    View searchplate = (View)searchView.findViewById(android.support.v7.appcompat.R.id.search_plate);
    searchplate.setBackgroundResource(R.drawable.texfield_searchview_holo_light);

    ImageView searchCloseIcon = (ImageView)searchView.findViewById(android.support.v7.appcompat.R.id.search_close_btn);
    searchCloseIcon.setImageResource(R.drawable.abc_ic_clear_normal);

    ImageView voiceIcon = (ImageView)searchView.findViewById(android.support.v7.appcompat.R.id.search_voice_btn);
    voiceIcon.setImageResource(R.drawable.abc_ic_voice_search);

    ImageView searchIcon = (ImageView)searchView.findViewById(android.support.v7.appcompat.R.id.search_mag_icon);
    searchIcon.setImageResource(R.drawable.abc_ic_search);


    return super.onCreateOptionsMenu(menu);
}
Abdul Rahman
fonte
1
isso não funciona para search_mag_icon. Dá "Estilo contém chave com entrada incorreta: 0x01010479"
Lavanya
1
a placa de busca não funciona para mim (ele faz algo, mas eu não consigo ver nenhuma mudança à linha de fundo), mas a idéia geral para AppCompat é muito útil
guy_m
14

Seu onCreateOptionsMenumétodo deve ser:

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.option, menu);
        SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
        int linlayId = getResources().getIdentifier("android:id/search_plate", null, null);
        ViewGroup v = (ViewGroup) searchView.findViewById(linlayId);
        v.setBackgroundResource(R.drawable.searchviewredversion);
        return super.onCreateOptionsMenu(menu);
    }

onde seu item de pesquisa está menu_searchfora do curso

e aqui está a searchviewredversion(esta é a versão xhdpi): http://img836.imageshack.us/img836/5964/searchviewredversion.png

insira a descrição da imagem aqui

VinceFR
fonte
existe alguma maneira de alterar o ícone Pesquisar e o botão Fechar de maneira semelhante?
Harsha MV
Eu não sei sobre o SherlockActionBar 4.2 Mas sim, você pode alterar o ícone de pesquisa e o botão Fechar da mesma maneira!
VinceFR
O ActionbarSherlock possui seus próprios temas e define seu próprio SearchView. Isso significa que você pode adicionar um item ao seu tema chamado searchViewTextField e usar a definição de desenho e os 9 patches acima.
NKijak
1
Não se esqueça de mudar o nome de arquivo para searchviewredversion.9.png para indicar ao recurso de exportação como 9-patch
1owk3y
13

A solução acima não funciona com o ActionBarSherlock 4.2 e, portanto, não é compatível com o Android 2.x. Aqui está o código de trabalho que configura o plano de fundo SearchView e o texto da dica no ActionBarSherlock 4.2:

public static void styleSearchView(SearchView searchView, Context context) {
    View searchPlate = searchView.findViewById(R.id.abs__search_plate);
    searchPlate.setBackgroundResource(R.drawable.your_custom_drawable);
    AutoCompleteTextView searchText = (AutoCompleteTextView) searchView.findViewById(R.id.abs__search_src_text);
    searchText.setHintTextColor(context.getResources().getColor(R.color.your_custom_color));
}
David Vávra
fonte
onde devo colocar esse código? Eu estou tentando fazer isso na versão 4.2 da barra de ação. minha pergunta stackoverflow.com/questions/13992424/…
Harsha MV
Oi, chame-o de onCreateOptionsMenu método. Encontre searchView e passe-o para este método.
David Vávra
Obrigado. Qualquer idéia de como remover esse símbolo em linha Mag como mostrado aqui i.imgur.com/YvBz2.png
Harsha MV
3
Com o ABS, você estenderá Theme.Sherlock ou Theme.Sherlock.Light, não os temas do Android. Isso significa que tudo que você precisa fazer é adicionar um item chamado searchViewTextField à definição de tema de seus aplicativos. Tudo feito em XML, não é necessário código.
NKijak
5

Estou cansado de fazer isso também e estou usando a v7. O aplicativo falhou quando tentei pegar a searchPlatevia o, getIdentifier()então fiz da seguinte maneira:

View searchPlate = searchView.findViewById(android.support.v7.appcompat.R.id.search_plate);
Eu faço
fonte
3

Eu também enfrentei o mesmo problema: usei a biblioteca appcompat v7 e defini o estilo personalizado para ela. Na pasta drawable, coloque o arquivo bottom_border.xml que se parece com isso:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
  <shape >
      <solid android:color="@color/blue_color" />
  </shape>
</item>
<item android:bottom="0.8dp"
  android:left="0.8dp"
  android:right="0.8dp">
  <shape >
      <solid android:color="@color/background_color" />
  </shape>
</item>

<!-- draw another block to cut-off the left and right bars -->
<item android:bottom="2.0dp">
  <shape >
      <solid android:color="@color/main_accent" />
  </shape>
 </item>
</layer-list>

Na pasta de valores styles_myactionbartheme.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <style name="AppnewTheme" parent="Theme.AppCompat.Light">
    <item name="android:windowBackground">@color/background</item>
    <item name="android:actionBarStyle">@style/ActionBar</item>
    <item name="android:actionBarWidgetTheme">@style/ActionBarWidget</item>
</style> 
<!-- Actionbar Theme -->
<style name="ActionBar" parent="Widget.AppCompat.Light.ActionBar.Solid.Inverse">
    <item name="android:background">@color/main_accent</item>
    <!-- <item name="android:icon">@drawable/abc_ic_ab_back_holo_light</item> -->
</style> 
<style name="ActionBarWidget" parent="Theme.AppCompat.Light">
    <!-- SearchView customization-->
     <!-- Changing the small search icon when the view is expanded -->
    <!-- <item name="searchViewSearchIcon">@drawable/ic_action_search</item> -->
     <!-- Changing the cross icon to erase typed text -->
  <!--   <item name="searchViewCloseIcon">@drawable/ic_action_remove</item> -->
     <!-- Styling the background of the text field, i.e. blue bracket -->
    <item name="searchViewTextField">@drawable/bottom_border</item>
     <!-- Styling the text view that displays the typed text query -->
    <item name="searchViewAutoCompleteTextView">@style/AutoCompleteTextView</item>        
</style>

  <style name="AutoCompleteTextView" parent="Widget.AppCompat.Light.AutoCompleteTextView">
    <item name="android:textColor">@color/text_color</item>
  <!--   <item name="android:textCursorDrawable">@null</item> -->
    <!-- <item name="android:textColorHighlight">@color/search_view_selected_text</item> -->
</style>
</resources>

Eu defini o arquivo custommenu.xml para exibir o menu:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:com.example.actionbartheme="http://schemas.android.com/apk/res-auto" >  

<item android:id="@+id/search"
      android:title="@string/search_title"
      android:icon="@drawable/search_buttonn" 
     com.example.actionbartheme:showAsAction="ifRoom|collapseActionView"   
                 com.example.actionbartheme:actionViewClass="android.support.v7.widget.SearchView"/>

Sua atividade deve estender o ActionBarActivity em vez de Activity.

@Override
public boolean onCreateOptionsMenu(Menu menu) 
{
    // Inflate the menu; this adds items to the action bar if it is present.
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.custommenu, menu);
}

No arquivo de manifesto:

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppnewTheme" >

Para mais informações, consulte aqui:
Aqui http://www.jayway.com/2014/06/02/android-theming-the-actionbar/

Suhas Patil
fonte
Confira: stackoverflow.com/questions/8211929/… para outro exemplo de LayerList.
Jared Burrows
3

Atualizar

Se você estiver usando o AndroidX, poderá fazê-lo assim

    View searchPlate = svSearch. findViewById(androidx.appcompat.R.id.search_plate);
    if (searchPlate != null) {
        AutoCompleteTextView searchText = searchPlate.findViewById(androidx.appcompat.R.id.search_src_text);
        if (searchText != null){
            searchText.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.edittext_text_size));
            searchText.setMaxLines(1);
            searchText.setSingleLine(true);
            searchText.setTextColor(getResources().getColor(R.color.etTextColor));
            searchText.setHintTextColor(getResources().getColor(R.color.etHintColor));
            searchText.setBackground(null);
        }
    }
Rashid
fonte
2

Primeiro, vamos criar um arquivo XML chamado search_widget_background.xml, para ser usado como um drawable, ou seja, no diretório drawable.

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <solid android:color="@color/red" />

</shape>

Este drawable será usado como pano de fundo para o nosso widget de pesquisa. Defino a cor para vermelho porque é o que você solicitou, mas você pode defini-la para qualquer cor definida pela tag @color. Você pode modificá-lo ainda mais usando os atributos definidos para a marca de forma (faça cantos arredondados, faça um plano de fundo oval etc.).

O próximo passo é definir o plano de fundo do nosso widget de pesquisa para este. Isso pode ser realizado pelo seguinte:

    public boolean onCreateOptionsMenu(Menu menu) {

        SearchView searchView = (SearchView)menu.findItem(R.id.my_search_view).getActionView();
        Drawable d = getResources().getDrawable(R.drawable.search_widget_background);
        searchView.setBackground(d);
...
    }
Erol
fonte
@shkschneider IMHO não funcionará, porque o plano de fundo deve ser definido em um elemento interno SearchView(nomeado search_plate), não em SearchViewsi mesmo. Veja minha resposta para mais detalhes. No entanto, tenho que admitir, não tentei usar a resposta de @ (baba tenor).
vArDo 26/07/12
Não percebeu que o SearchView estava no ActionBar. Agora deve funcionar.
Erol
@babatenor Isso não funcionará porque o plano de fundo por SearchViewsi só estará sempre abaixo do plano de fundo dos elementos que estão dentro SearchView. Existe uma LinearLayoutvisão interna SearchViewque tem id search_plate, que sets tem esse elemento sublinhado azul como plano de fundo. Veja minha resposta para detalhes. Portanto, com sua solução, o resultado é fundo azul para todo o widget, com sublinhado azul ainda visível. Eu testei no Jelly Bean , mas não acho que a versão de destino do SDK seja importante aqui.
vArDo 26/07/12
Obrigado vArDo. Eu conhecia a estrutura em camadas do SearchView, mas presumi que isso funcionaria (me pareceu lógico, pelo menos).
Erol
1
@babatenor Seria ótimo se ele trabalhou, de modo que tudo isso hackery não é necessário :)
Vardo
1
public boolean onCreateOptionsMenu(Menu menu) {
........

        // Set the search plate color
        int linlayId = getResources().getIdentifier("android:id/search_plate", null, null);
        View view = searchView.findViewById(linlayId);
        Drawable drawColor = getResources().getDrawable(R.drawable.searchcolor);
        view.setBackground( drawColor );
........
    }

e este é o arquivo searchablecolor.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
  <item>
      <shape >
          <solid android:color="#ffffff" />
      </shape>
  </item>

  <!-- main color -->
  <item android:bottom="1.5dp"
      android:left="1.5dp"
      android:right="1.5dp">
      <shape >
          <solid android:color="#2c4d8e" />
      </shape>
  </item>

  <!-- draw another block to cut-off the left and right bars -->
  <item android:bottom="18.0dp">
      <shape >
          <solid android:color="#2c4d8e" />
      </shape>
  </item>
</layer-list>
M.Raheel
fonte
0

Se você estiver inflando o Searchview como este "getMenuInflater (). Inflate (R.menu.search_menu, menu);". Em seguida, você pode personalizar essa pesquisa por meio do style.xml, como abaixo.

<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
      <item name="searchViewStyle">@style/SearchView.ActionBar</item>
</style>

<style name="SearchView.ActionBar" parent="Widget.AppCompat.SearchView.ActionBar">
      <item name="queryBackground">@drawable/drw_search_view_bg</item>
      <item name="searchHintIcon">@null</item>
      <item name="submitBackground">@null</item>
      <item name="closeIcon">@drawable/vd_cancel</item>
      <item name="searchIcon">@drawable/vd_search</item>
</style>
E Player Plus
fonte
0

Eu estava cavando muito sobre isso e finalmente encontrei esta solução e funciona para mim!
Você pode usar isso

Se você usa appcompat, tente o seguinte:

ImageView searchIconView = (ImageView) searchView.findViewById(android.support.v7.appcompat.R.id.search_button);
searchIconView.setImageResource(R.drawable.yourIcon);

Se você usa androidx, tente o seguinte:

ImageView searchIconView = (ImageView) searchView.findViewById(androidx.appcompat.R.id.search_button);
    searchIconView.setImageResource(R.drawable.yourIcon);

Ele mudará o ícone padrão do serchview.

Espero que ajude!

Marawan Walid
fonte