Изменение цвета курсора в SearchView без ActionBarSherlock

Я пытаюсь изменить цвет мигающего курсора в виджете SearchView в ICS+. Я пробовал следующее:

  • Добавляю <item name="android:textCursorDrawable">@null</item> в мою тему
  • Добавление стиля для AutoCompleteTextViews в мою тему и установка для textCursorAttribute этого стиля значения @null
  • Установка android:textCursorDrawable="@null" непосредственно в SearchView

Я прочитал ответ здесь (Пользовательский цвет курсора в SearchView), но нет стиль без ABS для searchAutoCompleteTextView, поэтому не удалось попробовать. Я также искал метод Java, чтобы сделать текстовый курсор доступным для рисования, но не смог его найти - я изменяю другие аспекты SearchView в Java и смог бы сделать это с помощью курсора, если бы был доступен метод.

Я довольно тщательно настроил SearchView, но это последнее изменение мешает ему выглядеть правильно — курсор белый на белом фоне, поэтому его нелегко увидеть. Любые другие идеи вещей, которые я могу попробовать?


person Eric Brynsvold    schedule 09.09.2013    source источник
comment
Если вы покопаетесь в исходном коде Android, вы обнаружите, что mCursorDrawableRes устанавливается только один раз в конструкторе с 3 параметрами. К сожалению, это означает, что нет простого способа изменить его во время выполнения. Похоже, ваши варианты могут быть ограничены использованием отражения или перемещением вашего пользовательского SearchView в android.widget для доступа к защищенному члену пакета.   -  person MH.    schedule 09.09.2013
comment
MH, спасибо за совет - я смог использовать отражение, чтобы добраться до mCursorDrawableRes в TextView и изменить его на 0 - что было эквивалентно установке его на @null, и цвет отображается правильно - если вы опубликуете это как ответ, Я приму это.   -  person Eric Brynsvold    schedule 10.09.2013
comment
Рад, что сработало, хотя решение не идеальное.   -  person MH.    schedule 10.09.2013
comment
Согласитесь, это не идеально — SearchView очень не настраивается из коробки. Мне пришлось изменить другие компоненты, используя findViewById и внутренние идентификаторы, чтобы получить компоненты из SearchView. Так что это похожее исправление на практике.   -  person Eric Brynsvold    schedule 10.09.2013


Ответы (4)


Основываясь на комментариях и ответах выше, я сделал пример того, как это может выглядеть с использованием отражения. Это решает проблему в моем приложении. Надеюсь, это сэкономит кому-то время.

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

Этот 0 может быть любым другим идентификатором ресурса, например R.drawable.my_cursor.

person Paul    schedule 05.11.2013
comment
У меня сработало, когда я попытался заменить строки 5 и 6 на final EditText searchTextView = (EditText) searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text); - person user1923613; 01.07.2014
comment
Отлично работает в API 16+. Отличное решение, никогда не найденное в stackoverflow - person djdance; 09.08.2014
comment
Спасибо, хороший ответ. В одном примечании к вашему комментарию вы сказали, что это устанавливает идентификатор ресурса курсора равным 0 или @null, что сделает его видимым на белом фоне. Установка его на ноль фактически делает цвет курсора по умолчанию таким же, как цвет текста, поэтому он будет работать на любом фоне, если вы уже правильно установили цвет текста. - person gkee; 11.12.2014
comment
Вау круто! Работал как шарм - person Edward van Raak; 01.01.2015
comment
@EricBrynsvold это правильный ответ. Пожалуйста, отметьте это как правильное. - person Sufian; 20.04.2015
comment
Мне пришлось использовать это для Appcompat: int textViewID = searchView.getContext() .getResources().getIdentifier("id/search_src_text", null, searchView.getContext().getPackageName()); - person Matt; 18.10.2016

Согласно предыдущему комментарию:

Если вы покопаетесь в исходном коде Android, вы обнаружите, что mCursorDrawableRes устанавливается только один раз в конструкторе с 3 параметрами. К сожалению, это означает, что нет простого способа изменить его во время выполнения. Похоже, ваши варианты могут быть ограничены использованием отражения или перемещением вашего пользовательского SearchView в пакет android.widget для доступа к защищенному элементу пакета.

person MH.    schedule 09.09.2013

Это изменяет цвет текста и работает также на 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));
    ...
person Gunnar Bernstein    schedule 05.01.2014
comment
Не работает на S5 и S4 с KitKat. На других устройствах не проверял. - person tomrozb; 14.11.2014

person    schedule
comment
что такое action_mode_close? Можно ли вместо этого установить цвет? - person android developer; 12.08.2015
comment
action_mode_close — это просто png. обычно белый цвет ☑. вы также можете использовать белый цвет вместо этого - person evan; 16.09.2015
comment
Не могли бы вы показать, как это сделать для новой библиотеки поддержки дизайна материалов? Я думаю, что единственный способ сделать это - либо установить реальное рисование для замены каретки, либо использовать colorControlActivated (но это также меняет и другие вещи). - person android developer; 16.09.2015