简体   繁体   English

Xamarin形式的android-绑定IsEnabled时设置浮动标签颜色

[英]Xamarin forms android - Set floating label color when binding IsEnabled

I extend an entry and i would like that it looked like this : Entry enable and disable 我扩展了一个条目,我希望它看起来像这样: 条目启用和禁用

Here is the renderer for android : 这是android的渲染器:

protected override void OnElementChanged(ElementChangedEventArgs<TextBox> e)
    {
        base.OnElementChanged(e);
        if (e.OldElement != null) this.SetNativeControl(null);

        if (e.NewElement == null) return;

        if (this.Control == null)
        {
            var layout = this.CreateNativeControl();

            this.editText.AddTextChangedListener(this);
            this.editText.ImeOptions = ImeAction.Done;

            if (this.Element.MaxLength != 0)
                this.editText.SetFilters(new IInputFilter[] { new InputFilterLengthFilter(this.Element.MaxLength) });

            this.SetNativeControl(layout);
        }

        this.ApplyEnabled();
        this.ApplyErrorText();
        this.ApplyPlaceholder();
        this.ApplyText();
        this.ApplyKeyboard();
        this.ApplyIsWrapping();
        this.ApplyBoxTextColor();

        this.SetHintLabelActiveColor();
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);

        if (e.PropertyName == nameof(this.Element.Placeholder))
            this.ApplyPlaceholder();
        else if (e.PropertyName == nameof(this.Element.IsInputValid) || e.PropertyName == nameof(this.Element.IsEnabled) || e.PropertyName == nameof(this.Element.IsMandatory))
            this.ApplyEnabled();
        else if (e.PropertyName == nameof(this.Element.ErrorText))
            this.ApplyErrorText();
        else if (e.PropertyName == nameof(this.Element.Placeholder))
            this.ApplyPlaceholder();
        else if (e.PropertyName == nameof(this.Element.Text))
            this.ApplyText();
        else if (e.PropertyName == nameof(this.Element.IsWrapping))
            this.ApplyIsWrapping();
        else if (e.PropertyName == nameof(this.Element.Keyboard))
            this.ApplyKeyboard();
        else if (e.PropertyName == nameof(this.Element.TextColor))
            this.ApplyBoxTextColor();
    }

    private void SetHintLabelDefaultColor(Color color)
    {
        var hint = this.textInputLayout.Class.GetDeclaredField("mDefaultTextColor");
        hint.Accessible = true;
        hint.Set(this.textInputLayout, new ColorStateList(new int[][] { new[] { 0 } }, new int[] { color }));
    }

    private void SetHintLabelActiveColor()
    {
        var hintText = this.textInputLayout.Class.GetDeclaredField("mFocusedTextColor");
        hintText.Accessible = true;
        hintText.Set(this.textInputLayout, new ColorStateList(new int[][] { new[] { 0 } }, new int[] { this.Element.FloatingLabelColor.ToAndroid() }));
    }

    private void ApplyText()
    {
        if (this.textInputLayout.EditText == null || this.textInputLayout.EditText.Text == this.Element.Text)
            return;

        this.textInputLayout.EditText.Text = this.Element.Text;
    }

    private void ApplyBoxTextColor()
    {
        this.textInputLayout.EditText?.SetTextColor(this.Element.TextColor.ToAndroid());
    }

    private void ApplyEnabled()
    {
        this.textInputLayout.EditText.Enabled = this.Element.IsEnabled;
        this.textInputLayout.EditText.SetCompoundDrawablesRelativeWithIntrinsicBounds(null, null, null, null);

        if (this.Element.IsEnabled)
        {
            this.ApplyIsInputValid();
            this.SetHintLabelDefaultColor(this.Element.FloatingLabelColor.ToAndroid());
            this.SetHintLabelActiveColor();
        }
        else
        {
            this.textInputLayout.EditText.SetPadding(0, 0, 0, 0);
            this.textInputLayout.EditText.BackgroundTintList = ColorStateList.ValueOf(Color.Transparent);
            this.SetHintLabelDefaultColor(Color.ParseColor("#9C9C9C"));
        }
    }

    private void ApplyErrorText()
    {
        this.textInputLayout.ErrorEnabled = true;
        this.textInputLayout.Error = this.Element.ErrorText;
    }

    private void ApplyIsInputValid()
    {
        if (!this.Element.IsInputValid.HasValue || this.Element.IsInputValid.Value)
        {
            this.textInputLayout.Error = null;
            if (!this.Element.IsInputValid.HasValue || (!this.Element.IsMandatory && string.IsNullOrWhiteSpace(this.Element.Text)))
                return;

            this.SetIconFromKey("ce-check", "#04d1cd");
        }
        else
        {
            this.SetIconFromKey("ce-Cross_close", "#ff6161");
        }
    }

    private void ApplyPlaceholder()
    {
        this.textInputLayout.HintEnabled = true;
        this.textInputLayout.HintAnimationEnabled = true;
        this.textInputLayout.Hint = this.Element.Placeholder;
    }
    private void ApplyIsWrapping()
    {
        if (this.Element.IsWrapping)
        {
            this.textInputLayout.EditText.InputType |= InputTypes.TextFlagCapSentences;
            this.textInputLayout.EditText.SetHorizontallyScrolling(false);
            this.textInputLayout.EditText.SetMaxLines(int.MaxValue);
        }
        else
        {
            this.textInputLayout.EditText.InputType &= ~InputTypes.TextFlagCapSentences;
            this.textInputLayout.EditText.SetHorizontallyScrolling(true);
            this.textInputLayout.EditText.SetMaxLines(1);
        }
    }

    private void ApplyKeyboard()
    {
        this.textInputLayout.EditText.InputType = this.Element.Keyboard.ToInputType();
    }

    private void SetIconFromKey(string key, string color)
    {
        var icon = Iconize.FindIconForKey(key);
        if (icon == null)
            return;

        var drawable = new IconDrawable(this.Context, icon).Color(Color.ParseColor(color)).SizeDp(17);
        this.textInputLayout.EditText.SetCompoundDrawablesRelativeWithIntrinsicBounds(null, null, drawable, null);
    }

But when property IsEnabled is binded, my floating label is gray and not blue (unless I have focus) whereas if IsEnabled = false Gray or IsEnabled = true Blue , the floating label is in the correct color. 但是,当绑定属性IsEnabled时,我的浮动标签是灰色而不是蓝色(除非我有焦点),而如果IsEnabled = false 灰色IsEnabled = true Blue ,则浮动标签的颜色正确。

The only solution if found was to make element focus and unfocus immediatly after applying isEnabled if it was true. 如果找到的唯一解决方案是在应用isEnabled后立即使元素成为焦点和焦点不集中(如果为true)。

For the life of me, I can't find a good solution. 对于我的一生,我找不到一个好的解决方案。 I don't know if it is me and I can't see it but I need help. 我不知道是不是我,也看不到,但是我需要帮助。

Thanks 谢谢

I found a solution, in my ViewModel, by default , my binding IsEnabled will be true and I set it to false when required. 我在ViewModel中找到了一个解决方案,默认情况下,我的绑定IsEnabled为true,并在需要时将其设置为false。

It works, thanks for your help. 可行,谢谢您的帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM