Android SearchView Formatting - android

Spent far too long on this problem now. Have solved most of it, but still struggling with the search hint icon. Having searched extensively this following bit of code does work in my fragment
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
mSearchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
mSearchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));
mSearchView.setIconifiedByDefault(true);
int id = mSearchView.getContext().getResources().getIdentifier("android:id/search_src_text", null, null);
mSearchViewTextView = (TextView) mSearchView.findViewById(id);
mSearchViewTextView.setTextColor(Color.WHITE);
mSearchViewTextView.setHintTextColor(Color.WHITE);
mSearchViewTextView.setBackgroundResource(R.drawable.action_textfield_search_alpha);
mSearchViewSsb = new SpannableStringBuilder(" ");
mSearchViewSsb.append(getResources().getString(R.string.fragment_friend_add_search_hint));
Drawable searchHintIcon = ContextCompat.getDrawable(MyApplication.getContext(), R.drawable.action_search);
int textSize = (int) (mSearchViewTextView.getTextSize() * 1.25);
searchHintIcon.setBounds(0, 0, textSize, textSize);
mSearchViewSsb.setSpan(new ImageSpan(searchHintIcon), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
mSearchViewTextView.setText(mSearchViewSsb);
int id1 = android.support.v7.appcompat.R.id.search_close_btn;
ImageView searchCloseIcon = (ImageView) mSearchView.findViewById(id1);
searchCloseIcon.setImageResource(R.drawable.action_close);
int id2 = android.support.v7.appcompat.R.id.search_button;
ImageView searchIcon = (ImageView) mSearchView.findViewById(id2);
searchIcon.setImageResource(R.drawable.action_search);
super.onCreateOptionsMenu(menu, getActivity().getMenuInflater());
mSearchView.setOnSearchClickListener(...);
mSearchView.setOnQueryTextListener(...);
}
However, it only works once when I call it in onCreateOptionsMenu. I have tried to reuse it in setOnQueryTextListener, but no matter what I do the application then either crashes or just ignores the change.
Also, when it is set once the curious thing is that the first time you have to press the cancel button twice, the first time you press the cancel button the SearchView TextView has all of the enhancements but the SearchHint Icon goes back to its original form.
All I need is that SearchHint icon to be white.
My theme is set to Theme.AppCompat.Light.DarkActionBar

If you just want to make the icon white you can add the following code to your menu file
<item
android:id="#+id/action_search"
android:icon="#drawable/abc_ic_search_api_mtrl_alpha"
android:title="#string/search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always|collapseActionView"/>

Related

Change color of android.support.v7.widget.SearchView

I am using search view.
<android.support.v7.widget.SearchView
android:id="#+id/searchView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="#+id/imageViewMenu"
>
</android.support.v7.widget.SearchView>
Is this possible to change text color and icon color to view?
Currently it shows black text and icon. I want to change it to white color text and white search icon.
This may work..
SearchView searchView = (SearchView) findViewById(R.id.search);
EditText searchEditText = (EditText)searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
searchEditText.setTextColor(getResources().getColor(R.color.white));
searchEditText.setHintTextColor(getResources().getColor(R.color.white));
For the android.support.v7.widget.SearchView you can change the text color, text hint color and the icon with this code :
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem searchMenuItem = menu.findItem(R.id.menu_action_search);
SearchView searchViewAction = (SearchView) MenuItemCompat.getActionView(searchMenuItem);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchableInfo searchableInfo = searchManager.getSearchableInfo(getComponentName());
searchViewAction.setSearchableInfo(searchableInfo);
searchViewAction.setIconifiedByDefault(true);
EditText searchEditText = (EditText)searchViewAction.findViewById(android.support.v7.appcompat.R.id.search_src_text);
searchEditText.setTextColor(getResources().getColor(R.color.white));
searchEditText.setHintTextColor(getResources().getColor(R.color.white));
ImageView searchMagIcon = (ImageView)searchViewAction.findViewById(android.support.v7.appcompat.R.id.search_button);
searchMagIcon.setImageResource(R.drawable.ic_search_white);
return super.onPrepareOptionsMenu(menu);
}
To Change the Text color :
int searchSrcTextId = getResources().getIdentifier("android:id/search_src_text", null, null);
EditText searchEditText = (EditText) searchView.findViewById(searchSrcTextId);
searchEditText.setTextColor(Color.WHITE);
searchEditText.setHintTextColor(Color.LTGRAY);
To Change the close button :
int closeButtonId = getResources().getIdentifier("android:id/search_close_btn", null, null);
ImageView closeButtonImage = (ImageView) searchView.findViewById(closeButtonId);
closeButtonImage.setImageResource(R.drawable.ic_action_cancel);
// This excerpt is from Android source code (SearchView.java)
mSearchButton = findViewById(R.id.search_button);
mSearchEditFrame = findViewById(R.id.search_edit_frame);
mSearchPlate = findViewById(R.id.search_plate);
mSubmitArea = findViewById(R.id.submit_area);
mSubmitButton = findViewById(R.id.search_go_btn);
mCloseButton = (ImageView) findViewById(R.id.search_close_btn);
mVoiceButton = findViewById(R.id.search_voice_btn);
mSearchHintIcon = (ImageView) findViewById(R.id.search_mag_icon);
Reference : link
If it resides in toolbar, set theme for toolbar. For example this makes the text(and icon) white
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" >
<item name="colorControlHighlight">#color/LightGray</item>
<item name="android:textColorHint">#color/LightGray</item>
<item name="android:editTextColor">#color/TransparentGray</item>
</style>
apply this theme to your toolbar hint that (colorControlHighlight) color of ripple effct of your menu items
Yes, you can do it, one of ways to do it:
public static void customizeSearchView(SearchView searchView) {
int searchTextViewId = searchView.getContext().getResources()
.getIdentifier("android:id/search_src_text", null, null);
AutoCompleteTextView searchTextView
= (AutoCompleteTextView) searchView.findViewById(searchTextViewId);
searchTextView.setTextSize(14);
searchTextView.setTextColor(Color.WHITE);
}

SearchView expand/collapse animation in Android

What I Have
I have a SearchView which does its work perfectly. But when I touch on it, it appears and disappears out of nothing. There is no transition animation playing on it and so it doesn't look good.
What I Want
I want a simple slide left and slide right animation to be played on the SearchView when it is expanded and collapsed respectively.
What I Tried
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
//Get the ID for the search bar LinearLayout
int searchBarId = searchView.getContext().getResources().getIdentifier("android:id/search_bar", null, null);
//Get the search bar Linearlayout
LinearLayout searchBar = (LinearLayout) searchView.findViewById(searchBarId);
//Give the Linearlayout a transition animation.
searchBar.setLayoutTransition(new LayoutTransition());
but the searchBar is always null so I can't set the layout transition on it.
Can I get a solution for it? Is my approach correct?
You can actually just grab the LinearLayout by doing the following:
LinearLayout searchBar = (LinearLayout) searchView.findViewById(R.id.search_bar);
So this is what you should write instead,
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
final int searchBarId = searchView.getContext().getResources().getIdentifier("android:id/search_bar", null, null); // Remove this line
// The modified Line
LinearLayout searchBar = (LinearLayout) searchView.findViewById(R.id.search_bar);
searchBar.setLayoutTransition(new LayoutTransition());
After reading the #Steven answer I got the solution given below
inside the onCreateOptionsMenu(Menu menu) method write the code
getMenuInflater().inflate(R.menu.meet_people_menu, menu);
final MenuItem searchItem = menu.findItem(R.id.app_bar_search);
SearchView searchView = (SearchView) searchItem.getActionView();
LinearLayout searchBar = (LinearLayout) searchView.findViewById(R.id.search_bar);
searchBar.setLayoutTransition(new LayoutTransition());
and here is my meet_people_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.jz.cso.activities.MeetPeopleActivity">
<item
android:title=""
android:id="#+id/app_bar_search"
android:icon="#drawable/ic_search_black_24dp"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always"
></item>
</menu>
View searchBar = searchView.findViewById(R.id.search_bar);
if (searchBar != null && searchBar instanceof LinearLayout) {
((LinearLayout) searchBar).setLayoutTransition(new LayoutTransition());
}

Change SearchView little magnifier icon

I want to change the little magnifier icon that looks like an EditText's drawableLeft on a SearchView.
I have tried the following:
This link shows the layout xml file for the whole Search Widget. So using this method (similar to reflection) I changed every icon excepting the little magnifier one:
int submitButtonId = searchView.getContext().getResources().getIdentifier("android:id/search_go_btn", null, null);
ImageView imageView = (ImageView) searchView.findViewById(submitButtonId);
imageView.setImageResource(submitIcon);
I tried changing both android:id/search_mag_icon and android:id/search_button, but the little magnifier inside the EditText is still gray (I just want a white one).
Still not beating, I proceed to make some hypothesis:
Since it didn't work it must be both ImageViews (corresponding to android:id/search_mag_icon and android:id/search_button) Then it must mean the icon is either a drawablePadding background or set up programatically.
"There is no android:drawableLeft nor android:drawableRight in the layout file so the first option is wrong...
Ergo, I proceed to confirm if it is indeed a background. NOPE, the background just covers the blue lines.
So, if the little magnifier is not an ImageView nor a drawableLeft/Right nor a background, It must have been set programmatically (Look for the nested class SearchAutoComplete, BUT NO!!!
So, how do I change this little magnifier icon? I have literally tried everything
Well this question took me about half an hour to write cause I wanted to rule out things I had already done, but I found the answer 5 mins after posting it: http://nlopez.io/how-to-style-the-actionbar-searchview-programmatically/
PS: yep, reflection all the way
In case someone is having this issue, What worked for me was:
searchView.setIconifiedByDefault(false); //This is what does the trick. Removing the magnifier icon.
ImageView searchHintIcon = (ImageView) searchView.findViewById(R.id.search_mag_icon);
searchHintIcon.setImageResource(R.drawable.ic_search_black);
Here is the whole method:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.home_search, menu);
// Associate searchable configuration with the SearchView
SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
searchView = (SearchView) menu.findItem(R.id.search_action).getActionView();
//If, this one returns null, use second option.
SearchableInfo searchableInfo = searchManager.getSearchableInfo(getActivity().getComponentName());
if (searchableInfo == null) {
searchableInfo = searchManager.getSearchableInfo(new ComponentName(getApplicationContext(), SearchActivity.class));
}
searchView.setSearchableInfo(searchableInfo);
searchView.setIconifiedByDefault(false);
try {
EditText searchEditText = (EditText) searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
searchEditText.setTextColor(getResources().getColor(R.color.black));
searchEditText.setHintTextColor(getResources().getColor(R.color.black));
ImageView searchHintIcon = (ImageView) searchView.findViewById(R.id.search_mag_icon);
searchHintIcon.setImageResource(R.drawable.ic_search_black);
Field f = TextView.class.getDeclaredField("mCursorDrawableRes");
f.setAccessible(true);
f.set(searchEditText, 0);
} catch (Exception e) {
e.printStackTrace();
}
}

SearchView remove blue focus line and show cursor at certain position

I have been trying to remove the blue focus line in the SearchView .I am casting it to a AutoCompleteTextView so that I can use customized icons for my searchView.
int id = searchView.getContext().getResources().getIdentifier("android:id/search_src_text", null, null);
searchtextView = (AutoCompleteTextView) searchView.findViewById(id);
I have tried using
searchtextView.setBackGroundColor(0)
and manually setting the background to #0000000 in my xml but I can still seee the blue line at the bottom.
The second problem I am facing is that the cursor does not show up on the text initially.I want to display the cursor when nothing is entered in the searchview.I tried to do it programmatically by using
if (searchtextView.getText().toString().length() >= 0) {
searchtextView.setSelection(searchtextView.getText().toString().length());
}
which should display the cursor even when no text exist inside the searchView.I think it has something to do with the focus because when I type in 2-3 characters the cursor shows up automatically.
I was able to solve it by setting the background of the default searchview plate as follows
int searchPlateId = searchView.getContext().getResources()
.getIdentifier("android:id/search_plate", null, null);
View searchPlateView = searchView.findViewById(searchPlateId);
if (searchPlateView != null) {
searchPlateView.setBackgroundColor(Color.BLACK);
}
This article helped.article link
You can use
android:queryBackground="#android:color/transparent"
I was able to make it work by clearingfocus on the search edit text during the menu creation function. Code below:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
...
final MenuItem searchItem = menu.findItem(R.id.action_search);
if (searchItem != null) {
// Associate searchable configuration with the SearchView
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
final SearchView view = (SearchView) searchItem.getActionView();
if(view !=null){
LinearLayout searchPlate = (LinearLayout)mSearchView.findViewById(R.id.search_plate);
if(searchPlate != null){
mSearchEditText = (EditText)searchPlate.findViewById(R.id.search_src_text);
if(mSearchEditText != null){
mSearchEditText.clearFocus(); // This fixes the keyboard from popping up each time
}
}
}
}
}

How to change the default icon on the SearchView, to be use in the action bar on Android?

I'm having a bit of trouble customizing the search icon in the SearchView. On my point of view, the icon can be changed in the Item attributes, right? Just check the code bellow..
Can someone tell me what I'm doing wrong?
This is the menu I'm using, with my custom search icon icn_lupa. But when I run the app, I always get the default search icon...
<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>
I've found another way to change the search icon which goes in the same line as Diego Pino's answer but straight in onPrepareOptionsMenu.
In your menu.xml (same as before)
<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>
In your activity:
#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);
}
I followed the example for changing the edittext in this example.
You should be able to do this for all icons/backgrounds in your SearchView, to find the right ID you can check here.
UPDATE November 2017:
Since this answer android has been updated with the possibility of changing the search icon through the XML.
If you target anything below android v21 you can use:
<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" />
Or v21 and later:
<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" />
And there are even more options:
closeIcon
commitIcon
goIcon
searchHintIcon
searchIcon
voiceIcon
Nice answer from #just_user
For my case, since I am using the appcompat v7 library for the SearchView + ActionBar, i modified his solution a bit to make it compatible to my project, it should work so as long as you did not modify anything when you added appcompat v7 as library
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 code:
#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);
}
Excuse for the very big icon (I have not resized the icon just yet), but it should work as it is.
I was struggling with this too but then I accidentaly used 'collapseActionView' and that fixed it!
My menu.xml looks like this now:
<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>
The downside of this is that on tablets the SearchView will appear on the left side of the ActionBar instead of where the searchicon is, but I don't mind that.
I defined a style to do it .
here is my 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"/>
and this is my style:
<style name="CitySearchView" parent="Base.Widget.AppCompat.SearchView">
<item name="searchIcon">#drawable/ic_more_search</item>
</style>
That it!
After finish that,just take a look at 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>
every item can be override by define a new style .
Hope it helps!
There's a way to do this. The trick is to recover the ImageView using its identifier and setting a new image with setImageResource(). This solution is inspired on Changing the background drawable of the searchview widget.
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) {
}
After some research I found the solution here. The trick is that the icon is not in an ImageView but in the Spannable object.
// 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);
In menu 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"/>
and create the 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"/>
then in activity's onCreateOptionsMenu or onPrepareOptionsMenu:
SearchView searchView = (SearchView) menu.findItem(R.id.menu_filter).getActionView();
searchView.setOnQueryTextListener(this);
It looks like the actionViewClass overides the icon and it doesn't look like you can change it from this class.
You got two solutions:
Live with it and I think it's the best option in terms of user experience and platform conformity.
Define your own actionViewClass
<SearchView
android:searchIcon="#drawable/ic_action_search"
..../>
use the searchIcon xml tag
This works with Material Design (MaterialComponents theme) and BottomAppBar.
If you are using androidx library, for example:
<item
android:id="#+id/sv"
android:title="#string/search"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="always" />
You can create a method and invoke it from wherever you want:
/**
* 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));
}
Usage example:
#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);
}
}
Update hint of AutocompleteTextView for updating search icon in the expanded mode, copied from android source,
#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);
}
From API 21 you can change it in xml:
android:searchIcon="#drawable/loupe"
android:closeIcon="#drawable/x_white"
for api level < 21, i did this:
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);
from this
to this
There are three magnifying glass icons. two of them are shown when IconizedByDefault is true(one which is shown before pressing and one is shown in the "hint") and one is shown all the time when IconizedByDefault is false. all the fields are private so the way to get them is by their xml id. (most of the code is mentioned separately in other answers in this post already)
when IconizedByDefault is true change the icon in the hint (which is seen only after pressing the icon) by :
mSearchSrcTextView = (SearchAutoComplete)findViewById(R.id.search_src_text);
then do the same as in the android source code:
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 was replaced with newSearchIconDrawable which is your new search icon.
Then set the hint with
mSearchSrcTextView.setHint(ssb);
The other 2 icons are in an ImageView, which can be found by their Id.
for the icon when searchview is closed (when iconizedByDefault is true) do:
mSearchButton = (ImageView) findViewById(R.id.search_button);
and for the one that always appears (if iconizedByDefault is false)
mCollapsedIcon = (ImageView) findViewById(R.id.search_mag_icon);
Desperate solution using 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
}
Hope it helps someone.
My solution:
Use two menu xml files. In one of the xmls the menu item has an actionView and in the other one no. Initially inflate the collapsed menu and when the menu item is clicked, invalidate the menu and inflate the expanded menu xml and make sure you call 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);
}
Just name your icon the same name as the icon that is used by the search view. When it compiles it takes the resource in the project over the icon in the library.
I use the AppCompat library. Yes, specifying android:icon="#drawable/search_icon_png" doesnt work.
So i looked into the source code of #style/Theme.AppCompat and found the icon that android uses.
<item name="searchViewSearchIcon">#drawable/abc_ic_search</item>
So if you rename your search icon inside your drawables to abc_ic_search.png, this icon is rendered as its found in your app drawable first, rather than the appcompat drawable folder.
Works for me :)
Using this approach you can customize the close and clear icons for the search widget as well.

Categories

Resources