Android 的自定义条目呈现器中的清除按钮问题

Clear Button issue in Custom Entry Renderer for Android

我正在为条目创建自定义渲染器。我主要是想在输入字段的左侧添加一个图标。我在 Android 中使用 SetCompoundDrawablesRelativeWithIntrinsicBounds() 并在 iOS 中使用 LeftView 实现了这一点。

当 ClearButtonVisibility 设置为 "while editing" 时会出现问题。在条目中输入内容并单击清除按钮后,左侧图标与文本一起被清除(这只发生在 Android 中。在 iOS 中,只有文本被清除。我意识到内置-in clear button image is in the compound drawables so I setting the compound drawables with my icon 以及内置图标。

最好的解决方法是什么?我希望这样当点击清除按钮时,只有文本被清除而不是图标。

注意:图标会暂时清除。当触发任何其他事件时,图标 returns.

CustomEntry - before click

CustomEntry - after click

CustomEntry - after some event

Android.Renderer:

[assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
namespace Styles.Android.Renderers
{
    public class CustomEntryRenderer : EntryRenderer
    {
        public CustomEntryRenderer(Context context) : base(context)
        {
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            // update control UI
            UpdateControl();

            base.OnElementPropertyChanged(sender, e);
        }

        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            // update control UI
            UpdateControl();

            base.OnElementChanged(e);
        }

        private void UpdateControl()
        {
            if (Element == null || Control == null)
                return;

            var entry = Element as CustomEntry;

            // set border/background
            var gradientBackground = new GradientDrawable();
            gradientBackground.SetShape(ShapeType.Rectangle);
            gradientBackground.SetColor(Element.BackgroundColor.ToAndroid());
            gradientBackground.SetCornerRadius(entry.CornerRadius);
            gradientBackground.SetStroke(entry.BorderWidth, entry.BorderColor.ToAndroid());
            Control.SetBackground(gradientBackground);

            // set appropriate icon
            int resID = Resources.GetIdentifier("icon_image", "drawable", this.Context.PackageName);
            var drawable = ContextCompat.GetDrawable(this.Context, resID);

            Control.SetCompoundDrawablesRelativeWithIntrinsicBounds(drawable, null, Control.GetCompoundDrawables()[2], null);
            Control.CompoundDrawablePadding = entry.IconPadding;
            paddingLeft = entry.IconPadding;               

            // set padding
            Control.SetPadding(Control.PaddingLeft, Control.PaddingTop, Control.PaddingRight, Control.PaddingBottom);
        }
    }
}

您将覆盖 OnTouchListener 以清理文本并再次 SetCompoundDrawable

像下面这样更改您的自定义渲染器:

[assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
namespace Styles.Android.Renderers
{
    public class CustomEntryRenderer : EntryRenderer
    {
        static Drawable drawableLeft;
        static Drawable drawableRight;
        public CustomEntryRenderer(Context context) : base(context)
        {
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            // update control UI
            UpdateControl();

            base.OnElementPropertyChanged(sender, e);
        }

        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            // update control UI
            UpdateControl();

            base.OnElementChanged(e);
        }

        private void UpdateControl()
        {
            if (Element == null || Control == null)
                return;

            var entry = Element as CustomEntry;

            // set border/background
            var gradientBackground = new GradientDrawable();
            gradientBackground.SetShape(ShapeType.Rectangle);
            gradientBackground.SetColor(Element.BackgroundColor.ToAndroid());
            gradientBackground.SetCornerRadius(entry.CornerRadius);
            gradientBackground.SetStroke(entry.BorderWidth, entry.BorderColor.ToAndroid());
            Control.SetBackground(gradientBackground);

            // set appropriate icon
            int resID = Resources.GetIdentifier("icon_image", "drawable", this.Context.PackageName);
            drawableLeft = ContextCompat.GetDrawable(this.Context, resID);
            drawableRight = Control.GetCompoundDrawables()[2];
            Control.SetCompoundDrawablesRelativeWithIntrinsicBounds(drawableLeft, null, drawableRight , null);
            Control.CompoundDrawablePadding = entry.IconPadding;
            paddingLeft = entry.IconPadding;               

            // set padding
            Control.SetPadding(Control.PaddingLeft, Control.PaddingTop, Control.PaddingRight, Control.PaddingBottom);

            Control.SetOnTouchListener(new OnDrawableTouchListener());
        }

     public class OnDrawableTouchListener : Java.Lang.Object, Android.Views.View.IOnTouchListener
     {
        public bool OnTouch(Android.Views.View v, MotionEvent e)
        {
            if (v is EditText && e.Action == MotionEventActions.Up)
            {
                EditText editText = (EditText)v;
                editText.SetCompoundDrawablesRelativeWithIntrinsicBounds(drawableLeft, null, drawableRight, null);
                if (drawableRight != null)
                {

                    bool touchable = e.GetX() > (editText.Width
                    - editText.PaddingRight - drawableRight.IntrinsicWidth)
                    && (e.GetX() < ((editText.Width - editText.PaddingRight)));
                    if (touchable)
                    {
                        Console.WriteLine(editText.Text);
                        editText.Text = "";
                        editText.SetCompoundDrawablesRelativeWithIntrinsicBounds(drawableLeft, null, drawableRight, null);
                        return true;
                    }

                }
            }

            return false;
        }

     }

    }
}