forked from xamarin/Xamarin.Forms
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMaterialFormsTextInputLayoutBase.cs
151 lines (127 loc) · 5.01 KB
/
MaterialFormsTextInputLayoutBase.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#if __ANDROID_28__
using System;
using Android.Content;
using Android.Support.Design.Widget;
using Android.Runtime;
using Android.Util;
using Android.Support.V4.View;
using Android.Content.Res;
using AView = Android.Views.View;
using Xamarin.Forms.Platform.Android.AppCompat;
using Xamarin.Forms.Platform.Android;
using Android.Widget;
namespace Xamarin.Forms.Material.Android
{
public class MaterialFormsTextInputLayoutBase : TextInputLayout
{
Color _formsTextColor;
Color _formsPlaceholderColor;
bool _isSetup = false;
ColorStateList _focusedFilledColorList;
ColorStateList _unfocusedEmptyColorList;
private ColorStateList _unfocusedUnderlineColorsList;
private ColorStateList _focusedUnderlineColorsList;
static readonly int[][] s_colorStates = { new[] { global::Android.Resource.Attribute.StateEnabled }, new[] { -global::Android.Resource.Attribute.StateEnabled } };
bool _isDisposed = false;
public MaterialFormsTextInputLayoutBase(Context context) : base(context)
{
}
public MaterialFormsTextInputLayoutBase(Context context, IAttributeSet attrs) : base(context, attrs)
{
}
public MaterialFormsTextInputLayoutBase(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr)
{
}
protected MaterialFormsTextInputLayoutBase(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
}
void ResetTextColors(Color formsTextColor, Color formsPlaceHolderColor)
{
_formsPlaceholderColor = formsPlaceHolderColor;
_formsTextColor = formsTextColor;
var underlineColors = MaterialColors.GetUnderlineColor(_formsTextColor);
var placeHolderColors = MaterialColors.GetPlaceHolderColor(_formsPlaceholderColor, _formsTextColor);
// I realize these are the same but I have to set it to a difference instance
// otherwise when focused it won't change to the color I want it to and it'll just think
// I'm not actually changing anything
_unfocusedUnderlineColorsList = MaterialColors.CreateEntryUnderlineColors(underlineColors.FocusedColor, underlineColors.UnFocusedColor);
_focusedUnderlineColorsList = MaterialColors.CreateEntryUnderlineColors(underlineColors.FocusedColor, underlineColors.UnFocusedColor);
_focusedFilledColorList = MaterialColors.CreateEntryFilledPlaceholderColors(placeHolderColors.FloatingColor, placeHolderColors.FloatingColor);
_unfocusedEmptyColorList = MaterialColors.CreateEntryFilledPlaceholderColors(placeHolderColors.InlineColor, placeHolderColors.FloatingColor);
var textColor = MaterialColors.GetEntryTextColor(formsTextColor).ToArgb();
EditText.SetTextColor(new ColorStateList(s_colorStates, new[] { textColor, textColor }));
}
internal void ApplyTheme(Color formsTextColor, Color formsPlaceHolderColor)
{
if (_isDisposed)
return;
if(!_isSetup)
{
_isSetup = true;
EditText.FocusChange += OnFocusChange;
ResetTextColors(formsTextColor, formsPlaceHolderColor);
}
else if(formsTextColor != _formsTextColor || _formsPlaceholderColor != formsPlaceHolderColor)
{
ResetTextColors(formsTextColor, formsPlaceHolderColor);
}
if(HasFocus)
ViewCompat.SetBackgroundTintList(EditText, _focusedUnderlineColorsList);
else
ViewCompat.SetBackgroundTintList(EditText, _unfocusedUnderlineColorsList);
if (HasFocus || !string.IsNullOrWhiteSpace(EditText.Text))
this.DefaultHintTextColor = _focusedFilledColorList;
else
this.DefaultHintTextColor = _unfocusedEmptyColorList;
}
void ApplyTheme() => ApplyTheme(_formsTextColor, _formsPlaceholderColor);
/*
* This currently does two things
* 1) It's a hacky way of keeping the underline color matching the TextColor.
* when the entry gets focused the underline gets changed to the themes active color
* and this is the only way to set it away from that and to whatever the user specified
* 2) The HintTextColor has a different alpha when focused vs not focused
* */
void OnFocusChange(object sender, FocusChangeEventArgs e)
{
if (EditText == null)
return;
Device.BeginInvokeOnMainThread(() => ApplyTheme());
// propagate the focus changed event to the View Renderer base class
if (Parent is AView.IOnFocusChangeListener focusChangeListener)
focusChangeListener.OnFocusChange(EditText, e.HasFocus);
}
internal void SetHint(string hint, VisualElement element)
{
HintEnabled = !string.IsNullOrWhiteSpace(hint);
if (HintEnabled)
{
element?.InvalidateMeasureNonVirtual(Internals.InvalidationTrigger.VerticalOptionsChanged);
Hint = hint;
// EditText.Hint => Hint
// It is impossible to reset it but you can make it invisible.
EditText.SetHintTextColor(global::Android.Graphics.Color.Transparent);
}
}
public override EditText EditText
{
get
{
if (this.IsDisposed())
return null;
return base.EditText;
}
}
protected override void Dispose(bool disposing)
{
if (!_isDisposed)
{
_isDisposed = true;
if (EditText != null)
EditText.FocusChange -= OnFocusChange;
}
base.Dispose(disposing);
}
}
}
#endif