Установка цвета курсора EditText с помощью метода отражения - PullRequest
0 голосов
/ 29 сентября 2018

Я использовал метод отражения, чтобы программно установить цвета курсора EditText, которые я нашел из этого ответа (я также пробовал этот ответ ).Однако, после некоторых последних обновлений, не могу точно вспомнить, когда этот метод больше не работает, я предполагаю, что Android, вероятно, изменил что-то в классе TextView.В любом случае, кто-нибудь может мне помочь с этим?Есть ли новые имена полей для mCursorDrawableRes и mCursorDrawable, или этот метод полностью недействителен и должен быть реализован другим способом сейчас?

Обновление: я только что обнаружил, что этот метод перестал работать только на AndroidP, в предыдущих версиях он все еще работал.

Обновление 2: я сам решил проблему, проверьте ответ, если вы тоже застряли.

Ответы [ 2 ]

0 голосов
/ 01 февраля 2019

К сожалению, Google не выставил атрибуты xml для tint или методы для установки их для рисования даже в библиотеках совместимости, поэтому в настоящее время единственный способ их динамической установки - это отражение, как описано.

Тем не менее, вы можете установить рисование в xml, и если вы просто хотите подкрасить существующие рисунки дизайна материала, это можно сделать, подкрашивая xml для маркеров выбора текста, так как они являются растровыми, но курсор можно нарисоватьэто вставка для рисования, поэтому ее нужно будет воссоздать из исходного кода.

Используются следующие рисунки:

R.drawable.abc_text_select_handle_left_mtrl_light
R.drawable.abc_text_select_handle_middle_mtrl_light
R.drawable.abc_text_select_handle_right_mtrl_light
R.drawable.abc_text_cursor_material

Вы можете создавать тонированные версии рисования дескриптора выбора текста следующим образом:

<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/abc_text_select_handle_left_mtrl_light"
    android:tint="@color/my_text_select_handle_color" />

<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/abc_text_select_handle_middle_mtrl_light"
    android:tint="@color/my_text_select_handle_color" />

<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/abc_text_select_handle_right_mtrl_light"
    android:tint="@color/my_text_select_handle_color" />

Рисованный курсор может быть воссоздан из исходного кода следующим образом:

<inset xmlns:android="http://schemas.android.com/apk/res/android"
       android:inset="2dp">
  <shape
      android:tint="@color/my_text_cursor_color"
      android:shape="rectangle">
    <size
        android:height="2dp"
        android:width="2dp" />
    <solid
        android:color="@color/white" />
  </shape>
</inset>

Поместите их в папку drawables и ссылайтесь на них в определении xml AppCompatEditText, используя:

android:textCursorDrawable
android:textSelectHandle
android:textSelectHandleLeft
android:textSelectHandleRight

и вуаля, пользовательский цветной курсор и маркеры выбора, которые точно соответствуют версии дизайна материала по умолчанию, которая позволяет избежать отражения, поэтому не вызовет предупреждений или ошибок.

0 голосов
/ 29 сентября 2018

ОК, после изучения исходного кода Android Pie я обнаружил, что Google изменил mCursorDrawable на mDrawableForCursor, а также изменил его тип с массива из двух элементов Drawable на просто Drawable, поэтому яВнесены некоторые изменения, основанные на оригинальном методе отражения, и теперь он работает для Android P:

 public static void setEditTextCursorColor(EditText editText, int color) {
    try {
        // Get the cursor resource id
        if(Build.VERSION.SDK_INT >= 28){//set differently in Android P (API 28)
            Field field = TextView.class.getDeclaredField("mCursorDrawableRes");
            field.setAccessible(true);
            int drawableResId = field.getInt(editText);

            // Get the editor
            field = TextView.class.getDeclaredField("mEditor");
            field.setAccessible(true);
            Object editor = field.get(editText);

            // Get the drawable and set a color filter
            Drawable drawable = ContextCompat.getDrawable(editText.getContext(), drawableResId);
            drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);

            // Set the drawables
            field = editor.getClass().getDeclaredField("mDrawableForCursor");
            field.setAccessible(true);
            field.set(editor, drawable);
        }else {
            Field field = TextView.class.getDeclaredField("mCursorDrawableRes");
            field.setAccessible(true);
            int drawableResId = field.getInt(editText);

            // Get the editor
            field = TextView.class.getDeclaredField("mEditor");
            field.setAccessible(true);
            Object editor = field.get(editText);

            // Get the drawable and set a color filter
            Drawable drawable = ContextCompat.getDrawable(editText.getContext(), drawableResId);
            drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
            Drawable[] drawables = {drawable, drawable};

            // Set the drawables
            field = editor.getClass().getDeclaredField("mCursorDrawable");
            field.setAccessible(true);
            field.set(editor, drawables);
        }
        setEditTextHandleColor(editText, color);
    } catch (Exception ignored) {
    }
}

Примечание: мне бы очень хотелось, чтобы Google мог просто добавить публичный метод, например setCursorDrawable () или что-то в этом роде,было бы намного проще.

...