在焦点侦听器中更改复合可绘制时,EditText会无限地触发焦点更改事件

时间:2018-02-23 18:19:05

标签: android xamarin xamarin.android android-edittext

我有一个自定义(x)控件,当它处于焦点并且有文本时,右侧有一个清晰的textbox图标。单击清除图标将删除textbox中的文本。不幸的是,当您点击drawable时,焦点更改事件会无限启动,因为更改focus change listener中的复合focus change events似乎会再激发两个public class CustomEditText : EditText { private Drawable clearButton; protected CustomEditText (IntPtr javaReference, JniHandleOwnership transfer) : base (javaReference, transfer) { } public CustomEditText (Context context) : base (context) { Init (); } public CustomEditText (Context context, IAttributeSet attrs) : base (context, attrs) { Init (attrs); } public CustomEditText (Context context, IAttributeSet attrs, int defStyle) : base (context, attrs, defStyle) { Init (attrs); } protected void Init (IAttributeSet attrs = null) { // Set up clear button SetupClearButton (); SetupEvents (); } private void SetupClearButton () { clearButton = ContextCompat.GetDrawable (Android.App.Application.Context, Resource.Drawable.forms_edit_text_clear_gray); clearButton.SetBounds (0, 0, clearButton.IntrinsicWidth, clearButton.IntrinsicHeight); } private void SetupEvents () { // Handle clear button visibility this.TextChanged += (sender, e) => { if (this.HasFocus) UpdateClearButton (); }; this.FocusChange += (object sender, FocusChangeEventArgs e) => { UpdateClearButton (e.HasFocus);// Gets called infinitely }; // Handle clearing the text this.Touch += (sender, e) => { if (this.GetCompoundDrawables ()[2] != null && e.Event.Action == MotionEventActions.Up && e.Event.GetX () > (this.Width - this.PaddingRight - clearButton.IntrinsicWidth)) { this.Text = ""; UpdateClearButton (); e.Handled = true; } else e.Handled = false; }; } private void UpdateClearButton (bool hasFocus = true) { var compoundDrawables = this.GetCompoundDrawables (); var compoundDrawable = this.Text.Length == 0 || !hasFocus ? null : clearButton; if (compoundDrawables[2] != compoundDrawable) this.SetCompoundDrawables (compoundDrawables[0], compoundDrawables[1], compoundDrawable, compoundDrawables[3]); } } ,首先关注焦点,第二个关注焦点。知道如何在没有无限循环的情况下使其工作吗?

以下是代码:

{{1}}

2 个答案:

答案 0 :(得分:1)

我移植了DroidParts'使用Android的支持库窗口小部件时使用的ClearableEditTextXamarin.Android是不合适的。

注意:DroidParts在Apache 2.0许可下,因此我无法将我的C#衍生版全部发布到StackOverflow,但避免连续焦点更改的关键在于OnTouch和{ {1}}方法以及将侦听器添加到 base EditText小部件的事实。

完整代码@ https://gist.github.com/sushihangover/01a7965aae75d8ef0589697aa8f0e750

OnFocusChange

enter image description here

enter image description here

enter image description here

原始StackOverflow Q / A:How to create EditText with cross(x) button at end of it?

答案 1 :(得分:1)

在我看来,我最简单的实现是:

 public class ClearableEditext : EditText
{
    Context mContext;
    Drawable imgX;

    public ClearableEditext(Context context) : base(context)
    {
        init(context, null);
    }
    public ClearableEditext(Context context, Android.Util.IAttributeSet attrs) : base(context, attrs)
    {
        init(context, attrs);
    }
    public ClearableEditext(Context context, Android.Util.IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr)
    {
        init(context, attrs);
    }
    public ClearableEditext(Context context, Android.Util.IAttributeSet attrs, int defStyleAttr, int defStyleRes) : base(context, attrs, defStyleAttr, defStyleRes)
    {
        init(context, attrs);
    }

    public void init(Context ctx, Android.Util.IAttributeSet attrs)
    {
        mContext = ctx;
        imgX = ContextCompat.GetDrawable(ctx, Android.Resource.Drawable.PresenceOffline);
        imgX.SetBounds(0, 0, imgX.IntrinsicWidth, imgX.IntrinsicHeight);
        manageClearButton();
        this.SetOnTouchListener(new TouchHelper(this, imgX));
        this.AddTextChangedListener(new TextListener(this));
    }

    public void manageClearButton()
    {
        if (this.Text.ToString().Equals(""))
            removeClearButton();
        else
            addClearButton();
    }
    public void addClearButton()
    {
        this.SetCompoundDrawables(this.GetCompoundDrawables()[0],
                this.GetCompoundDrawables()[1],
                imgX,
                this.GetCompoundDrawables()[3]);
    }
    public void removeClearButton()
    {
        this.SetCompoundDrawables(this.GetCompoundDrawables()[0],
                this.GetCompoundDrawables()[1],
                null,
                this.GetCompoundDrawables()[3]);
    }
}

public class TouchHelper : Java.Lang.Object, View.IOnTouchListener
{
    ClearableEditext Editext;
    public ClearableEditext objClearable { get; set; }
    Drawable imgX;
    public TouchHelper(ClearableEditext editext, Drawable imgx)
    {
        Editext = editext;
        objClearable = objClearable;
        imgX = imgx;
    }
    public bool OnTouch(View v, MotionEvent e)
    {
        ClearableEditext et = Editext;

        if (et.GetCompoundDrawables()[2] == null)
            return false;
        // Only do this for up touches
        if (e.Action != MotionEventActions.Up)
            return false;
        // Is touch on our clear button?
        if (e.GetX() > et.Width - et.PaddingRight - imgX.IntrinsicWidth)
        {
            Editext.Text = string.Empty;
            if (objClearable != null)
                objClearable.removeClearButton();

        }
        return false;
    }
}

public class TextListener : Java.Lang.Object, ITextWatcher
{
    public ClearableEditext objClearable { get; set; }
    public TextListener(ClearableEditext objRef)
    {
        objClearable = objRef;
    }

    public void AfterTextChanged(IEditable s)
    {

    }

    public void BeforeTextChanged(ICharSequence s, int start, int count, int after)
    {

    }

    public void OnTextChanged(ICharSequence s, int start, int before, int count)
    {
        if (objClearable != null)
            objClearable.manageClearButton();
    }
}

可能寿司有更好的答案,但我建议你试试这个。

要将x图标更改为自定义图标,请在init()

中更改图像