EditText 光标和指针没有正确改变颜色
EditText cursor and pointer not changing colour properly
我的应用程序有 4 种样式,每种都有不同的 colorAccent
。根据用户操作,使用的样式可能会发生变化,colorAccent
.
也会发生变化
还有两个 somewhat-static
EditText
视图(这些视图不会在应用程序的生命周期中消失,因为它们存在在应用程序的“主页”页面中 )。作为参考,我们假设我有:
2 次浏览
EditTextA
EditTextB
4 种风格
StyleR
与 Red
作为 colorAccent
StyleG
与 Green
作为 colorAccent
StyleB
与 Blue
作为 colorAccent
StyleY
与 Yellow
作为 colorAccent
如果我将 StyleR
作为当前样式并点击 EditTextA
,光标将立即显示为红色。如果我将样式更改为 StyleG
,点击 EditTextA
,键入内容并 select 它,我将有一个 红色 光标和 green 指针在它下面。同时,如果我点击 EditTextB
,光标将是 绿色。
我已经尝试 Invalidate()
和 PostInvalidate()
两个视图在 RunOnUiThread
中,但它们不会更正它们的颜色。
在样式更改之间膨胀的任何其他 EditText
都会获得正确的颜色。
基于,我已经设法在 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)
{
}
}
我的应用程序有 4 种样式,每种都有不同的 colorAccent
。根据用户操作,使用的样式可能会发生变化,colorAccent
.
还有两个 somewhat-static
EditText
视图(这些视图不会在应用程序的生命周期中消失,因为它们存在在应用程序的“主页”页面中 )。作为参考,我们假设我有:
2 次浏览
EditTextA
EditTextB
4 种风格
StyleR
与Red
作为colorAccent
StyleG
与Green
作为colorAccent
StyleB
与Blue
作为colorAccent
StyleY
与Yellow
作为colorAccent
如果我将 StyleR
作为当前样式并点击 EditTextA
,光标将立即显示为红色。如果我将样式更改为 StyleG
,点击 EditTextA
,键入内容并 select 它,我将有一个 红色 光标和 green 指针在它下面。同时,如果我点击 EditTextB
,光标将是 绿色。
我已经尝试 Invalidate()
和 PostInvalidate()
两个视图在 RunOnUiThread
中,但它们不会更正它们的颜色。
在样式更改之间膨胀的任何其他 EditText
都会获得正确的颜色。
基于
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)
{
}
}