我试图通过编程更改edittext的颜色。它可以工作,但正如您从所附的图像中看到的,文本选择的图标仍然使用主题颜色重音,而不是我设置的蓝色。我怎样才能改变它?我目前的代码是:
editText.setBackgroundTintList(new ColorStateList(new int[][]{StateSet.WILD_CARD}, new int[]{color}));
setCursorDrawableColor(editText, color);
private void setCursorDrawableColor(EditText editText, int color) {
try {
Field fCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes");
fCursorDrawableRes.setAccessible(true);
int mCursorDrawableRes = fCursorDrawableRes.getInt(editText);
Field fEditor = TextView.class.getDeclaredField("mEditor");
fEditor.setAccessible(true);
Object editor = fEditor.get(editText);
Class<?> clazz = editor.getClass();
Field fCursorDrawable = clazz.getDeclaredField("mCursorDrawable");
fCursorDrawable.setAccessible(true);
Drawable[] drawables = new Drawable[2];
Resources res = editText.getContext().getResources();
drawables[0] = res.getDrawable(mCursorDrawableRes);
drawables[1] = res.getDrawable(mCursorDrawableRes);
drawables[0].setColorFilter(color, PorterDuff.Mode.SRC_IN);
drawables[1].setColorFilter(color, PorterDuff.Mode.SRC_IN);
fCursorDrawable.set(editor, drawables);
} catch (final Throwable ignored) {
}
}
以下是基于乔恩答案的Xamarin解决方案
public static void SetHandlesColor(EditText editText, Color color)
{
try
{
if (Build.VERSION.SdkInt >= BuildVersionCodes.Q)
{
var size = SpToPx(22, editText.Context);
var corner = size / 2f;
var inset = SpToPx(10, editText.Context);
//left drawable
var drLeft = new GradientDrawable(GradientDrawable.Orientation.BottomTop, new[] { (int)color, color });
drLeft.SetSize(size, size);
drLeft.SetCornerRadii(new[] { corner, corner, 0f, 0f, corner, corner, corner, corner });
editText.TextSelectHandleLeft = new InsetDrawable(drLeft, inset, 0, inset, inset);
//right drawable
var drRight = new GradientDrawable(GradientDrawable.Orientation.BottomTop, new[] { (int)color, color });
drRight.SetSize(size, size);
drRight.SetCornerRadii(new[] { 0f, 0f, corner, corner, corner, corner, corner, corner });
editText.TextSelectHandleRight = new InsetDrawable(drRight, inset, 0, inset, inset);
//middle drawable
var drMiddle = new GradientDrawable(GradientDrawable.Orientation.BottomTop, new[] { (int)color, color });
drMiddle.SetSize(size, size);
drMiddle.SetCornerRadii(new[] { 0f, 0f, corner, corner, corner, corner, corner, corner });
var mInset = (int)(System.Math.Sqrt(2f) * corner - corner);
var insetDrawable = new InsetDrawable(drMiddle, mInset, mInset, mInset, mInset);
var rotateDrawable = new RotateDrawable();
rotateDrawable.Drawable = insetDrawable;
rotateDrawable.ToDegrees = 45f;
rotateDrawable.SetLevel(10000);
editText.TextSelectHandle = rotateDrawable;
return;
}
var editorField = Class.FromType(typeof(TextView)).GetDeclaredField("mEditor");
if (!editorField.Accessible)
editorField.Accessible = true;
var editor = editorField.Get(editText);
var editorClass = editor.Class;
string[] handleNames = { "mSelectHandleLeft", "mSelectHandleRight", "mSelectHandleCenter" };
string[] resNames = { "mTextSelectHandleLeftRes", "mTextSelectHandleRightRes", "mTextSelectHandleRes" };
for (int i = 0; i < handleNames.Length; i++)
{
var handleField = editorClass.GetDeclaredField(handleNames[i]);
if (!handleField.Accessible)
{
handleField.Accessible = true;
}
Drawable handleDrawable = (Drawable)handleField.Get(editor);
if (handleDrawable == null)
{
var resField = Class.FromType(typeof(TextView)).GetDeclaredField(resNames[i]);
if (!resField.Accessible)
{
resField.Accessible = true;
}
int resId = resField.GetInt(editText);
handleDrawable = ContextCompat.GetDrawable(editText.Context, resId);
}
if (handleDrawable != null)
{
Drawable drawable = handleDrawable.Mutate();
drawable.SetColorFilter(color, PorterDuff.Mode.SrcIn);
handleField.Set(editor, drawable);
}
}
}
catch (ReflectiveOperationException) { }
catch (Exception ex)
{
Crashes.TrackError(ex);
}
}
public static int SpToPx(float sp, Context context)
{
return (int)TypedValue.ApplyDimension(ComplexUnitType.Sp, sp, context.Resources.DisplayMetrics);
}
Kotlin版本,适用于api 14至api 32
fun TextView.setHandlesColor(@ColorInt color: Int) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val size = 22.spToPx(context).toInt()
val corner = size.toFloat() / 2
val inset = 10.spToPx(context).toInt()
//left drawable
val drLeft = GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, intArrayOf(color, color))
drLeft.setSize(size, size)
drLeft.cornerRadii = floatArrayOf(corner, corner, 0f, 0f, corner, corner, corner, corner)
setTextSelectHandleLeft(InsetDrawable(drLeft, inset, 0, inset, inset))
//right drawable
val drRight = GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, intArrayOf(color, color))
drRight.setSize(size, size)
drRight.cornerRadii = floatArrayOf(0f, 0f, corner, corner, corner, corner, corner, corner)
setTextSelectHandleRight(InsetDrawable(drRight, inset, 0, inset, inset))
//middle drawable
val drMiddle = GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, intArrayOf(color, color))
drMiddle.setSize(size, size)
drMiddle.cornerRadii = floatArrayOf(0f, 0f, corner, corner, corner, corner, corner, corner)
val mInset = (sqrt(2f) * corner - corner).toInt()
val insetDrawable = InsetDrawable(drMiddle, mInset, mInset, mInset, mInset)
val rotateDrawable = RotateDrawable()
rotateDrawable.drawable = insetDrawable
rotateDrawable.toDegrees = 45f
rotateDrawable.level = 10000
setTextSelectHandle(rotateDrawable)
return
}
try {
val editorField = TextView::class.java.getFieldByName("mEditor")
val editor = editorField?.get(this) ?: this
val editorClass: Class<*> = if (editorField != null) editor.javaClass else TextView::class.java
val handles = androidx.collection.ArrayMap<String, String>(3).apply {
put("mSelectHandleLeft", "mTextSelectHandleLeftRes")
put("mSelectHandleRight", "mTextSelectHandleRightRes")
put("mSelectHandleCenter", "mTextSelectHandleRes")
}
for (i in 0..handles.size) {
editorClass.getFieldByName(handles.keyAt(i))?.let { field: Field ->
val drawable = field.get(editor) as? Drawable
?: TextView::class.java.getFieldByName(handles.valueAt(i))
?.getInt(this)
?.let { ContextCompat.getDrawable(context, it) }
if(drawable != null) field.set(editor, drawable.tinted(color))
}
}
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
}
fun Class<*>.getFieldByName(name: String): Field? = try {
this.getDeclaredField(name).apply { isAccessible = true }
} catch (t: Throwable) {
null
}
fun Number.spToPx(context: Context? = null): Float {
val res = context?.resources ?: android.content.res.Resources.getSystem()
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, this.toFloat(), res.displayMetrics)
}
fun Drawable.tinted(@ColorInt color: Int): Drawable = when {
this is VectorDrawableCompat -> {
this.apply { setTintList(ColorStateList.valueOf(color)) }
}
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && this is VectorDrawable -> {
this.apply { setTintList(ColorStateList.valueOf(color)) }
}
else -> {
DrawableCompat.wrap(this)
.also { DrawableCompat.setTint(it, color) }
.let { DrawableCompat.unwrap(it) }
}
}
我更喜欢使用样式。xml
来设置此样式。但是,可以按如下方式以编程方式进行:
1.突出颜色
首先是突出显示的颜色。这可以通过以下方式进行设置:
editText.setHighlightColor(color);
2.左右标记
左边和右边的标记仍然没有用这个着色。继续使用反射方法,我们应该对这些选择标记执行相同的操作:
// Left
Field fCursorDrawableLeftRes = TextView.class.getDeclaredField("mTextSelectHandleLeftRes");
fCursorDrawableLeftRes.setAccessible(true);
int mCursorDrawableLeftRes = fCursorDrawableLeftRes.getInt(editText);
// Right
Field fCursorDrawableRightRes = TextView.class.getDeclaredField("mTextSelectHandleRightRes");
fCursorDrawableRightRes.setAccessible(true);
int mCursorDrawableRightRes = fCursorDrawableRightRes.getInt(editText);
当然还有:将其添加到drawables列表以更新它们(从您的来源更新):
Drawable[] drawables = new Drawable[3];
Resources res = editText.getContext().getResources();
drawables[0] = res.getDrawable(mCursorDrawableRes);
drawables[1] = res.getDrawable(mCursorDrawableLeftRes);
drawables[2] = res.getDrawable(mCursorDrawableRightRes);
drawables[0].setColorFilter(color, PorterDuff.Mode.SRC_IN);
drawables[1].setColorFilter(color, PorterDuff.Mode.SRC_IN);
drawables[2].setColorFilter(color, PorterDuff.Mode.SRC_IN);
3.结果
这意味着您的方法将类似于:
private void setCursorDrawableColor(EditText editText, int color) {
try {
Field fCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes");
fCursorDrawableRes.setAccessible(true);
int mCursorDrawableRes = fCursorDrawableRes.getInt(editText);
// Left
Field fCursorDrawableLeftRes = TextView.class.getDeclaredField("mTextSelectHandleLeftRes");
fCursorDrawableLeftRes.setAccessible(true);
int mCursorDrawableLeftRes = fCursorDrawableLeftRes.getInt(editText);
// Right
Field fCursorDrawableRightRes = TextView.class.getDeclaredField("mTextSelectHandleRightRes");
fCursorDrawableRightRes.setAccessible(true);
int mCursorDrawableRightRes = fCursorDrawableRightRes.getInt(editText);
Field fEditor = TextView.class.getDeclaredField("mEditor");
fEditor.setAccessible(true);
Object editor = fEditor.get(editText);
Class<?> clazz = editor.getClass();
Field fCursorDrawable = clazz.getDeclaredField("mCursorDrawable");
fCursorDrawable.setAccessible(true);
Drawable[] drawables = new Drawable[3];
Resources res = editText.getContext().getResources();
drawables[0] = res.getDrawable(mCursorDrawableRes);
drawables[1] = res.getDrawable(mCursorDrawableLeftRes);
drawables[2] = res.getDrawable(mCursorDrawableRightRes);
drawables[0].setColorFilter(color, PorterDuff.Mode.SRC_IN);
drawables[1].setColorFilter(color, PorterDuff.Mode.SRC_IN);
drawables[2].setColorFilter(color, PorterDuff.Mode.SRC_IN);
fCursorDrawable.set(editor, drawables);
} catch (final Throwable ignored) {}
}
//其他方法(使用styles.xml
)
如我所说,我更喜欢使用styles.xml来实现此行为,在这种情况下,仅使用以下三个属性将导致想要的行为:
<item name="colorControlNormal">@android:color/holo_green_dark</item>
<item name="colorControlActivated">@android:color/holo_green_dark</item>
<item name="colorControlHighlight">@android:color/holo_green_dark</item>
(当然还有突出显示的textColorHighlight
)
我已经读过一些关于颜色的线程,但所有这些线程都必须通过style.xml进行设置。 现在我用这个来确定颜色。 是否可以不使用XML,例如使用代码来更改SwitchCompat/Checkbox的颜色?
在Android系统中,我们可以通过以下方式更改光标颜色: android:textCursorDrawable=“@drawable/black\u color\u cursor”。 我们如何动态地做到这一点? 在我的情况下,我已经将光标绘图为白色,但我需要改变黑色怎么办?
我正在尝试通过代码更改白色标记图像的颜色。我已经阅读了下面的代码应该改变颜色,但我的标记仍然是白色的。 我错过了什么吗?有没有其他方法可以更改位于我的res文件夹中的可绘制对象的颜色?
我在中有一个,底线颜色不是我想要的,我不知道如何更改它。 这是我到目前为止所拥有的。 出于某种不起作用的奇怪原因,应该是它。
我在应用程序中使用微调器和TextInputText,当用户选择微调器项目时,我想更改一些EditText功能(Curor和HintText颜色)。这是我的代码: 我不知道为什么这样不行。有人能帮我吗?
我想知道它是否可能以编程方式进行,以及如何在选中RadioButton时以编程方式更改其颜色? PS:我不想使用XML 在XML中,我使用这样的东西及其工作: 在我style.xml 我如何通过编程实现这一点?