programing

Android의 작업 표시 줄에서 사용할 SearchView의 기본 아이콘을 변경하는 방법은 무엇입니까?

yoursource 2021. 1. 16. 10:50
반응형

Android의 작업 표시 줄에서 사용할 SearchView의 기본 아이콘을 변경하는 방법은 무엇입니까?


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>

미리 감사드립니다.


actionViewClass가 아이콘을 덮어 쓰고이 클래스 에서 변경할 수없는 것처럼 보입니다 .

두 가지 해결책이 있습니다.


Diego Pino의 답변과 같은 줄에 있지만 .NET에서 곧바로 검색 아이콘을 변경하는 다른 방법을 찾았습니다 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

@just_user의 좋은 답변

제 경우에는 SearchView + ActionBar에 appcompat v7 라이브러리를 사용하고 있기 때문에 프로젝트와 호환되도록 그의 솔루션을 약간 수정했습니다. 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>

자바 코드 :

@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가 searchicon이있는 곳 대신 ActionBar의 왼쪽에 나타날 것이라는 점입니다.


나는 그것을 할 스타일을 정의했다.

다음은 내 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>

모든 항목은 새 스타일을 정의하여 재정의 할 수 있습니다.

도움이 되었기를 바랍니다.


이를 수행하는 방법이 있습니다. 트릭은 식별자를 사용하여 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));        
}

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

몇 가지 조사 끝에 여기 에서 해결책을 찾았습니다 . 트릭은 아이콘이 in이 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);

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

searchIcon xml 태그 사용


Android 소스에서 복사 한 확장 모드에서 검색 아이콘을 업데이트하기위한 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);
    }

API 21에서 xml로 변경할 수 있습니다.

android:searchIcon="@drawable/loupe"
android:closeIcon="@drawable/x_white"

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

이것으로부터

여기에 이미지 설명 입력

이에

여기에 이미지 설명 입력


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

3 개의 돋보기 아이콘이 있습니다. 두 개는 IconizedByDefault가 true 일 때 (하나는 누르기 전에 표시되고 다른 하나는 "힌트"에 표시됨) IconizedByDefault가 false 일 때 항상 표시됩니다. 모든 필드는 비공개이므로 가져 오는 방법은 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은 새 검색 아이콘 인 newSearchIconDrawable로 대체되었습니다. 그런 다음 힌트를 설정하십시오.

mSearchSrcTextView.setHint(ssb); 

다른 2 개의 아이콘은에 있으며 ImageViewID로 찾을 수 있습니다. searchview가 닫힐 때 아이콘에 대해 (iconizedByDefault가 true 일 때) 다음을 수행하십시오.

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

항상 표시되는 항목 (iconizedByDefault가 false 인 경우)

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

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
}

누군가에게 도움이되기를 바랍니다.


이것은 Material Design (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);
    }
}

내 솔루션 : 두 개의 메뉴 xml 파일을 사용하십시오. XML 중 하나에서 메뉴 항목에는 actionView가 있고 다른 하나에는 no가 있습니다. 처음에는 축소 된 메뉴를 확장하고 메뉴 항목을 클릭하면 메뉴를 무효화하고 확장 된 메뉴 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);
}

검색보기에서 사용하는 아이콘과 동일한 이름으로 아이콘 이름을 지정하십시오. 컴파일 할 때 라이브러리의 아이콘 위로 프로젝트의 리소스를 가져옵니다.


AppCompat 라이브러리를 사용합니다. 예, 지정이 android:icon="@drawable/search_icon_png"작동하지 않습니다. 그래서 @ style / Theme.AppCompat의 소스 코드를 살펴보고 안드로이드가 사용하는 아이콘을 찾았습니다.

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

따라서 드로어 블 내부의 검색 아이콘 이름을로 바꾸면 abc_ic_search.png이 아이콘은 appcompat 드로어 블 폴더가 아닌 앱 드로어 블에서 먼저 발견 된 것으로 렌더링됩니다. 나를 위해 작동합니다 :)

이 접근 방식을 사용하면 검색 위젯의 닫기 및 지우기 아이콘도 사용자 정의 할 수 있습니다.

참조 URL : https://stackoverflow.com/questions/10445760/how-to-change-the-default-icon-on-the-searchview-to-be-use-in-the-action-bar-on

반응형