0
votes

I extend an entry and i would like that it looked like this :Entry enable and disable

Here is the renderer for 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.

The only solution if found was to make element focus and unfocus immediatly after applying isEnabled if it was 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

1
I didn't understand your question. So only when you focus the element, you get the desired colors? Are you sure the methods are being called when you switch the properties?Bruno Caceiro
Could you please share a basic demo so that we can test it ?AbbyWang - MSFT
Exactly @bcaceiro, with the binding, my floating label will be gray because it is false initially. When my binding value change to true, my breaking point in OnElementPropertyChanged will be hit but it will not change the color of my floating label. If I don't set the IsEnabled property via Binding, it works like a charmTristan

1 Answers

0
votes

I found a solution, in my ViewModel, by default , my binding IsEnabled will be true and I set it to false when required.

It works, thanks for your help.