我有一个有4种风格的应用程序,每种风格都有不同的colorAccent
。根据用户操作,正在使用的样式可能会发生变化,colorAccent
也会发生变化。
还有两个somewhat-static
EditText
视图(这些视图不会在应用程序的生命周期中消失,因为它们出现在应用程序的“主页”页面中)。作为参考,让我们假设我有:
EditTextA
EditTextB
StyleR
与Red
作为colorAccent
StyleG
与Green
作为colorAccent
StyleB
与Blue
作为colorAccent
StyleY
与Yellow
作为colorAccent
如果我将StyleR
作为当前样式并点击EditTextA
,光标将立即显示为红色。如果我将样式更改为StyleG
,点击EditTextA
,键入内容并选择它,我将有一个红色光标,下方有绿色指针。同时,如果我点击EditTextB
,光标将变为绿色。
我试过Invalidate()
和PostInvalidate()
在RunOnUiThread
内的两个视图,但他们不会纠正他们的颜色。
在样式更改之间膨胀的任何其他EditText
都会获得正确的颜色。
基于this answer by Jared Rummler,我已经设法在Xamarin中做我想做的事。这是我最终得到的代码:
public static void SetCursorColor( this EditText editText, Resources resources, Int32 colorResourceId ) {
try {
TextView
textViewTemplate = new TextView( editText.Context );
//
// EditText Cursor
//
var field = textViewTemplate.Class.GetDeclaredField( "mCursorDrawableRes" );
field.Accessible = true;
Int32 drawableResId = field.GetInt( editText );
field = textViewTemplate.Class.GetDeclaredField( "mEditor" );
field.Accessible = true;
var editor = field.Get( editText );
Drawable drawable = resources.GetDrawable( drawableResId );
drawable.SetColorFilter( resources.GetColor( colorResourceId ), PorterDuff.Mode.SrcIn );
Drawable[] drawables = { drawable, drawable };
field = editor.Class.GetDeclaredField( "mCursorDrawable" );
field.Accessible = true;
field.Set( editor, drawables );
//
// EditText Pointer
//
String[]
fieldsNames = { "mTextSelectHandleLeftRes", "mTextSelectHandleRightRes", "mTextSelectHandleRes" },
drawablesNames = { "mSelectHandleLeft", "mSelectHandleRight", "mSelectHandleCenter" };
for( Int32 index = 0; index < fieldsNames.Length && index < drawablesNames.Length; index++ ) {
String
fieldName = fieldsNames[ index ],
drawableName = drawablesNames[ index ];
field = textViewTemplate.Class.GetDeclaredField( fieldName );
field.Accessible = true;
Int32 handle = field.GetInt( editText );
Drawable handleDrawable = resources.GetDrawable( handle );
handleDrawable.SetColorFilter( resources.GetColor( colorResourceId ), PorterDuff.Mode.SrcIn );
field = editor.Class.GetDeclaredField( drawableName );
field.Accessible = true;
field.Set( editor, handleDrawable );
}
} catch( Exception exception ) {
}
}
我只需要Android项目的白色光标和指针,并基于“auhmaan”答案我在Droid Renderer中编写了这个代码,它的工作原理。也许这对某人有帮助:
if (Control != null && Element != null)
{
// set the cursor color the same as the entry TextColor
IntPtr IntPtrtextViewClass = JNIEnv.FindClass(typeof(TextView));
IntPtr mCursorDrawableResProperty =
JNIEnv.GetFieldID(IntPtrtextViewClass, "mCursorDrawableRes", "I");
// replace 0 with a Resource.Drawable.my_cursor
JNIEnv.SetField(Control.Handle, mCursorDrawableResProperty, 0);
try
{
TextView textViewTemplate = new TextView(Control.Context);
var field = textViewTemplate.Class.GetDeclaredField("mEditor");
field.Accessible = true;
var editor = field.Get(Control);
//
// EditText Pointer
//
String[]
fieldsNames = { "mTextSelectHandleLeftRes", "mTextSelectHandleRightRes", "mTextSelectHandleRes" },
drawablesNames = { "mSelectHandleLeft", "mSelectHandleRight", "mSelectHandleCenter" };
for (Int32 index = 0; index < fieldsNames.Length && index < drawablesNames.Length; index++)
{
String
fieldName = fieldsNames[index],
drawableName = drawablesNames[index];
field = textViewTemplate.Class.GetDeclaredField(fieldName);
field.Accessible = true;
Int32 handle = field.GetInt(Control);
Drawable handleDrawable = Resources.GetDrawable(handle);
handleDrawable.SetColorFilter(Xamarin.Forms.Color.White.ToAndroid(), PorterDuff.Mode.SrcIn);
field = editor.Class.GetDeclaredField(drawableName);
field.Accessible = true;
field.Set(editor, handleDrawable);
}
}
catch (Exception ex)
{
}
}