Как изменить программный цвет курсора Edittext в Android?
В андроиде мы можем изменить цвет курсора с помощью:
android:textCursorDrawable="@drawable/black_color_cursor"
.
Как мы можем сделать это динамически?
В моем случае я настроил курсор на белый, но мне нужно изменить черный Как сделать?
// Set an EditText view to get user input
final EditText input = new EditText(nyactivity);
input.setTextColor(getResources().getColor(R.color.black));
Ответы
Ответ 1
Использование некоторого отражения сделало трюк для меня
Java:
// https://github.com/android/platform_frameworks_base/blob/kitkat-release/core/java/android/widget/TextView.java#L562-564
Field f = TextView.class.getDeclaredField("mCursorDrawableRes");
f.setAccessible(true);
f.set(yourEditText, R.drawable.cursor);
XML:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#ff000000" />
<size android:width="1dp" />
</shape>
Вот метод, который вы можете использовать, которому не нужен XML:
public static void setCursorColor(EditText view, @ColorInt int color) {
try {
// Get the cursor resource id
Field field = TextView.class.getDeclaredField("mCursorDrawableRes");
field.setAccessible(true);
int drawableResId = field.getInt(view);
// Get the editor
field = TextView.class.getDeclaredField("mEditor");
field.setAccessible(true);
Object editor = field.get(view);
// Get the drawable and set a color filter
Drawable drawable = ContextCompat.getDrawable(view.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);
} catch (Exception ignored) {
}
}
Ответ 2
android:textCursorDrawable="@null"
Затем в приложении:
final EditText input = new EditText(nyactivity);
input.setTextColor(getResources().getColor(R.color.black));
Получите отсюда
Ответ 3
Это перезаписанная версия функции из @Jared Rummler с несколькими улучшениями:
- Поддержка Android 4.0.x
- Специальная функция
getDrawable(Context, int)
getDrawable(int)
устарела для API 22 и выше.
private static final Field
sEditorField,
sCursorDrawableField,
sCursorDrawableResourceField;
static {
Field editorField = null;
Field cursorDrawableField = null;
Field cursorDrawableResourceField = null;
boolean exceptionThrown = false;
try {
cursorDrawableResourceField = TextView.class.getDeclaredField("mCursorDrawableRes");
cursorDrawableResourceField.setAccessible(true);
final Class<?> drawableFieldClass;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
drawableFieldClass = TextView.class;
} else {
editorField = TextView.class.getDeclaredField("mEditor");
editorField.setAccessible(true);
drawableFieldClass = editorField.getType();
}
cursorDrawableField = drawableFieldClass.getDeclaredField("mCursorDrawable");
cursorDrawableField.setAccessible(true);
} catch (Exception e) {
exceptionThrown = true;
}
if (exceptionThrown) {
sEditorField = null;
sCursorDrawableField = null;
sCursorDrawableResourceField = null;
} else {
sEditorField = editorField;
sCursorDrawableField = cursorDrawableField;
sCursorDrawableResourceField = cursorDrawableResourceField;
}
}
public static void setCursorColor(EditText editText, int color) {
if (sCursorDrawableField == null) {
return;
}
try {
final Drawable drawable = getDrawable(editText.getContext(),
sCursorDrawableResourceField.getInt(editText));
drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
sCursorDrawableField.set(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN
? editText : sEditorField.get(editText), new Drawable[] {drawable, drawable});
} catch (Exception ignored) {
}
}
private static Drawable getDrawable(Context context, int id) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
return context.getResources().getDrawable(id);
} else {
return context.getDrawable(id);
}
}
Ответ 4
Нам удалось это сделать:
- Создание файла макета с помощью только EditText и цвета курсора, установленного в xml на нем.
- Надувание
- Использование EditText, поскольку вы использовали бы программно созданный
Ответ 5
Вдохновленный @Jared Rummler и @Oleg Barinov, я разработал решение, которое также работает на API 15 -
public static void setCursorColor(EditText editText, @ColorInt int color) {
try {
// Get the cursor resource id
Field field = TextView.class.getDeclaredField("mCursorDrawableRes");
field.setAccessible(true);
int drawableResId = field.getInt(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};
if (Build.VERSION.SDK_INT == 15) {
// Get the editor
Class<?> drawableFieldClass = TextView.class;
// Set the drawables
field = drawableFieldClass.getDeclaredField("mCursorDrawable");
field.setAccessible(true);
field.set(editText, drawables);
} else {
// Get the editor
field = TextView.class.getDeclaredField("mEditor");
field.setAccessible(true);
Object editor = field.get(editText);
// Set the drawables
field = editor.getClass().getDeclaredField("mCursorDrawable");
field.setAccessible(true);
field.set(editor, drawables);
}
} catch (Exception e) {
Log.e(LOG_TAG, "-> ", e);
}
}
Ответ 6
Мне было бы интересно, как я могу изменить ширину курсора. Например, если я переключаю EditText в пользовательский режим перезаписи (мне нужен широко мигающий курсор; с сохранением текущей ширины курсора) и когда вернусь в режим вставки, снова установите предыдущую сохраненную ширину курсора.