59

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>

前もって感謝します。

4

19 に答える 19

98

検索アイコンを変更する別の方法を見つけました。これは、Diego Pinoの回答と同じ行にありますが、まっすぐです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確認できる正しいIDを見つけるために、のすべてのアイコン/背景に対してこれを実行できるはずです。

これが他の誰かにも役立つことを願っています!

2017年11月の更新:

この回答以降、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
于 2013-08-21T14:43:20.670 に答える
37

@just_userからのいい答え

私の場合、SearchView +ActionBarにappcompatv7ライブラリを使用しているので、プロジェクトと互換性があるようにソリューションを少し変更しました。appcompatv7を追加したときに何も変更しなかった場合は、機能するはずです。図書館

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

非常に大きなアイコン(まだアイコンのサイズを変更していません)の申し訳ありませんが、そのまま動作するはずです。

ここに画像の説明を入力してください

于 2014-08-02T06:17:53.813 に答える
20

私もこれに苦労していましたが、誤って「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の左側に表示されることですが、私はそれを気にしません。

于 2013-07-20T13:53:18.370 に答える
15

私はそれを行うためのスタイルを定義しました。

これが私の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>

それ!</ p>

それが終わったら、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>

新しいスタイルを定義することで、すべてのアイテムをオーバーライドできます。

それが役に立てば幸い!

于 2015-04-17T07:40:22.023 に答える
14

これを行う方法があります。秘訣は、識別子を使用してImageViewを回復し、。を使用して新しい画像を設定することsetImageResource()です。このソリューションは、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));        
}
于 2013-06-07T16:19:43.160 に答える
6

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) {
    }
于 2014-08-26T12:47:39.243 に答える
5

いくつかの調査の後、私はここで解決策を見つけました。秘訣は、アイコンがオブジェクト内ではなくオブジェクト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);
于 2014-05-13T20:27:45.770 に答える
4

メニュー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);
于 2018-02-28T09:29:50.247 に答える
3

actionViewClassがアイコンを上書きしているように見えますが、このクラスからアイコンを変更できるようには見えません。

2つの解決策があります。

  • それと一緒に暮らすと、ユーザーエクスペリエンスとプラットフォームの適合性の点でそれが最良の選択肢だと思います。
  • 独自のactionViewClassを定義する
于 2012-05-04T09:11:12.733 に答える
3
<SearchView
            android:searchIcon="@drawable/ic_action_search"
..../>

searchIconxmlタグを使用します

于 2016-04-04T19:15:27.803 に答える
3

これは、マテリアルデザイン(MaterialComponentsテーマ)およびBottomAppBarで機能します。

androidxライブラリを使用している場合、例:

 <item
    android:id="@+id/sv"
    android:title="@string/search"
    app:actionViewClass="androidx.appcompat.widget.SearchView"
    app:showAsAction="always" />

メソッドを作成して、どこからでも呼び出すことができます。

  /**
 * Set SearchView Icon
 * @param i Drawable icon
 */
private void setSVIcon(int i) {
    ImageView iv = searchView.findViewById(androidx.appcompat.R.id.search_button);
    iv.setImageDrawable(ResourcesCompat.getDrawable(getResources(), i, null));
}

使用例:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(m, menu);
    MenuItem mn = menu.findItem(R.id.sv);
    if (mn != null) {
        searchview = (SearchView) mn.getActionView();
        setSVIcon(R.drawable.ic_sr);
    }
}
于 2019-06-28T23:40:24.923 に答える
2

アンドロイドソースからコピーされた、拡張モードで検索アイコンを更新するためのAutocompleteTextViewのヒントを更新します。

@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);
    }
于 2014-11-03T19:05:03.843 に答える
1

API 21から、xmlで変更できます。

android:searchIcon="@drawable/loupe"
android:closeIcon="@drawable/x_white"
于 2015-01-26T09:21:04.883 に答える
1

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

これから

ここに画像の説明を入力してください

これに

ここに画像の説明を入力してください

于 2015-07-09T04:48:08.883 に答える
1

3つの虫眼鏡アイコンがあります。2つはIconizedByDefaultがtrueの場合に表示され(1つは押す前に表示され、もう1つは「ヒント」に表示されます)、もう1つはIconizedByDefaultがfalseの場合に常に表示されます。すべてのフィールドはプライベートであるため、それらを取得する方法はxmlIDによるものです。(コードのほとんどは、この投稿の他の回答ですでに個別に言及されています)

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がfalseの場合)

mCollapsedIcon = (ImageView) findViewById(R.id.search_mag_icon);
于 2016-11-21T11:26:47.617 に答える
1

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
}

それが誰かを助けることを願っています。

于 2017-12-07T11:57:55.453 に答える
0

私の解決策:2つのメニューxmlファイルを使用します。xmlの1つでは、メニュー項目にactionViewがあり、もう1つではありません。最初に折りたたまれたメニューを膨らませ、メニュー項目がクリックされたら、メニューを無効にし、展開されたメニュー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);
}
于 2013-08-27T17:07:27.940 に答える
0

アイコンに、検索ビューで使用されるアイコンと同じ名前を付けるだけです。コンパイルすると、ライブラリのアイコンよりもプロジェクトのリソースが使用されます。

于 2014-07-16T14:06:08.767 に答える
-1

AppCompatライブラリを使用しています。はい、指定は機能しandroid:icon="@drawable/search_icon_png"ません。そこで、@ style / Theme.AppCompatのソースコードを調べて、Androidが使用するアイコンを見つけました。

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

したがって、ドローアブル内の検索アイコンの名前をに変更するとabc_ic_search.png、このアイコンは、appcompatドローアブルフォルダーではなく、アプリドローアブルで最初に見つかったものとしてレンダリングされます。私のために働く:)

このアプローチを使用すると、検索ウィジェットの閉じるアイコンとクリアアイコンをカスタマイズすることもできます。

于 2014-04-03T22:36:53.517 に答える