8

I am attempting to change the color of the blinking cursor on the SearchView widget in ICS+. I have tried the following:

  • Adding <item name="android:textCursorDrawable">@null</item> to my theme
  • Adding a style for AutoCompleteTextViews to my theme and setting the textCursorAttribute of that style to @null
  • Setting android:textCursorDrawable="@null" directly on the SearchView

I read the answer here (Custom cursor color in SearchView), but there is not a non-ABS style for searchAutoCompleteTextView, so could not try this. I also looked for a Java method to set the text cursor drawable, but could not find one - I am modifying other aspects of the SearchView in Java and would be able to do so with the cursor if there were a method available.

I have customized the SearchView pretty extensively, but this one last change is keeping it from looking right - the cursor is white on a white background, so it is not easily visible. Any other ideas of things I can try?

Community
  • 1
  • 1
Eric Brynsvold
  • 2,880
  • 3
  • 17
  • 22
  • 1
    If you dig into the Android source code, you'll find that `mCursorDrawableRes` only gets set once in the 3-param constructor. Unfortunately that means there is no easy way to change it at runtime. Looks like your options may be limited to using reflection, or moving your custom `SearchView` into the `android.widget` in order to access the package protected member. – MH. Sep 09 '13 at 19:32
  • MH, thanks for the tip - I was able to use reflection to get to mCursorDrawableRes in TextView and change it to 0 - which was the equivalent of setting it to @null and the color shows up correctly - if you post this as an answer, I'll accept it. – Eric Brynsvold Sep 09 '13 at 20:05
  • Glad that worked out, even though the solution isn't ideal. – MH. Sep 09 '13 at 20:26
  • Agreed it is not ideal - the SearchView is very uncustomizable out of the box. I had to change other components by using findViewById and internal IDs to get the components from the SearchView. So this is a similar fix in practice. – Eric Brynsvold Sep 09 '13 at 20:30

4 Answers4

57

Based on the comments and answers above I made an example of how this could look using reflection. This solves the problem in my app. Hope it saves someone else some time.

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.entity_list_actions, menu);
    final SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
    final int textViewID = searchView.getContext().getResources().getIdentifier("android:id/search_src_text",null, null);
    final AutoCompleteTextView searchTextView = (AutoCompleteTextView) searchView.findViewById(textViewID);
    try {
        Field mCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes");
        mCursorDrawableRes.setAccessible(true);
        mCursorDrawableRes.set(searchTextView, 0); //This sets the cursor resource ID to 0 or @null which will make it visible on white background
    } catch (Exception e) {}
    return super.onCreateOptionsMenu(menu);
}

That 0 could be any other resource ID like R.drawable.my_cursor

Paul
  • 1,907
  • 2
  • 21
  • 29
  • 20
    What worked for me is when I tried to replace lines 5 and 6 with `final EditText searchTextView = (EditText) searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);` – user1923613 Jun 30 '14 at 20:29
  • Work fine in API 16+. Great solution, never found on stackoverflow – djdance Aug 09 '14 at 10:36
  • Thanks, nice answer. One note on your comment, you said "This sets the cursor resource ID to 0 or @null which will make it visible on white background". Setting it to null actually makes the cursor colour default to be the same as the text colour, so it will work on any background if you've got the text colour set right already. – gkee Dec 11 '14 at 04:52
  • Wow nice! Worked like a charm – Edward van Raak Jan 01 '15 at 16:05
  • @EricBrynsvold this is the correct answer. Please mark this one as correct. – Sufian Apr 20 '15 at 10:34
  • I had to use this for Appcompat: `int textViewID = searchView.getContext()
.getResources().getIdentifier("id/search_src_text", null, searchView.getContext().getPackageName());` – Matt Oct 18 '16 at 13:19
3
<style name="CustomTheme" parent="android:Theme.Holo.Light">
    ...
    <item name="android:autoCompleteTextViewStyle">@style/SearchViewStyle</item>
    ...
</style>

<style name="SearchViewStyle" parent="@android:style/Widget.Holo.Light.AutoCompleteTextView">
    <item name="android:textCursorDrawable">@drawable/action_mode_close</item>
</style>
evan
  • 318
  • 3
  • 14
  • what's "action_mode_close" ? Is it possible to set the color instead? – android developer Aug 12 '15 at 06:46
  • action_mode_close is just a png. usually the ☑ whit white color. you can also whit color instead – evan Sep 16 '15 at 14:25
  • 1
    Can you please show how to do it for the new material design support library? I think the only way to do it there is to either set a real drawable to replace the caret, or use colorControlActivated (yet this also changes other things too). – android developer Sep 16 '15 at 20:20
1

As per earlier comment:

If you dig into the Android source code, you'll find that mCursorDrawableRes only gets set once in the 3-param constructor. Unfortunately that means there is no easy way to change it at runtime. Looks like your options may be limited to using reflection, or moving your custom SearchView into the android.widget package in order to access the package protected member.

MH.
  • 45,303
  • 10
  • 103
  • 116
1

This changes the text color and works also on Android 8:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main_menu_search, menu);
        MenuItem searchItem = menu.findItem(R.id.action_search);
        SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
        SearchView.SearchAutoComplete theTextArea = (SearchView.SearchAutoComplete) searchView
                .findViewById(R.id.search_src_text);
        theTextArea.setTextColor(getResources().getColor(R.color.yourColor));
    ...
Gunnar Bernstein
  • 6,074
  • 2
  • 45
  • 67