EditText 光标和指针没有正确改变颜色

EditText cursor and pointer not changing colour properly

我的应用程序有 4 种样式,每种都有不同的 colorAccent。根据用户操作,使用的样式可能会发生变化,colorAccent.

也会发生变化

还有两个 somewhat-static EditText 视图(这些视图不会在应用程序的生命周期中消失,因为它们存在在应用程序的“主页”页面中 )。作为参考,我们假设我有:

2 次浏览

4 种风格

如果我将 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)
        {
        }
    }