8
8
import android .content .Context ;
9
9
import android .content .res .TypedArray ;
10
10
import android .graphics .Canvas ;
11
- import android .graphics .Color ;
12
11
import android .graphics .Paint ;
13
12
import android .support .v4 .content .ContextCompat ;
14
13
import android .support .v7 .widget .AppCompatEditText ;
15
14
import android .text .Editable ;
16
- import android .text .TextPaint ;
17
15
import android .util .AttributeSet ;
18
16
import android .view .ActionMode ;
19
17
import android .view .Menu ;
23
21
24
22
public class OtpEditText extends AppCompatEditText {
25
23
public static final String XML_NAMESPACE_ANDROID = "http://schemas.android.com/apk/res/android" ;
26
- private int defStyleAttr = 0 ;
27
-
28
- private float mSpace = 8 ; //24 dp by default, space between the lines
29
- private float mCharSize ;
30
- private float mNumChars = 6 ;
31
- private float mLineSpacing = 10 ; //8dp by default, height of the text from our lines
32
- private int mMaxLength = 6 ;
33
24
34
25
private OnClickListener mClickListener ;
35
26
36
- private float mLineStroke = 1 ; //1dp by default
37
- private float mLineStrokeSelected = 2 ; //2dp by default
38
27
private Paint mLinesPaint ;
28
+ private Paint mStrokePaint ;
39
29
40
- private int mMainColor ;
30
+ private int defStyleAttr = 0 ;
31
+ private int mMaxLength = 6 ;
32
+ private int mPrimaryColor ;
41
33
private int mSecondaryColor ;
42
34
private int mTextColor ;
43
35
44
- private Paint mStrokePaint ;
36
+ private float mLineStrokeSelected = 2 ; //2dp by default
37
+ private float mLineStroke = 1 ; //1dp by default
38
+ private float mSpace = 8 ; //24 dp by default, space between the lines
39
+ private float mCharSize ;
40
+ private float mNumChars = 6 ;
41
+ private float mLineSpacing = 10 ; //8dp by default, height of the text from our lines
42
+
43
+ private String mBoxStyle ;
44
+
45
+ private final String ROUNDED_BOX = "rounded_box" ;
46
+ private final String UNDERLINE = "underline" ;
47
+ private final String SQUARE_BOX = "square_box" ;
48
+ private final String ROUNDED_UNDERLINE = "rounded_underline" ;
45
49
46
50
public OtpEditText (Context context ) {
47
51
super (context );
@@ -65,11 +69,10 @@ private void init(Context context, AttributeSet attrs) {
65
69
float multi = context .getResources ().getDisplayMetrics ().density ;
66
70
mLineStroke = multi * mLineStroke ;
67
71
mLineStrokeSelected = multi * mLineStrokeSelected ;
72
+
68
73
mLinesPaint = new Paint (getPaint ());
69
- mStrokePaint = new Paint (getPaint ());
70
- mStrokePaint .setStrokeWidth (4 );
71
- mStrokePaint .setStyle (Paint .Style .STROKE );
72
74
mLinesPaint .setStrokeWidth (mLineStroke );
75
+
73
76
setBackgroundResource (0 );
74
77
mSpace = multi * mSpace ; //convert to pixels for our density
75
78
mNumChars = mMaxLength ;
@@ -108,9 +111,41 @@ private void getAttrsFromTypedArray(AttributeSet attributeSet) {
108
111
final TypedArray a = getContext ().obtainStyledAttributes (attributeSet , R .styleable .OtpEditText , defStyleAttr , 0 );
109
112
110
113
mMaxLength = attributeSet .getAttributeIntValue (XML_NAMESPACE_ANDROID , "maxLength" , 4 );
111
- mMainColor = a .getColor (R .styleable .OtpEditText_oev_primary_color , getResources ().getColor (android .R .color .holo_red_dark ));
114
+ mPrimaryColor = a .getColor (R .styleable .OtpEditText_oev_primary_color , getResources ().getColor (android .R .color .holo_red_dark ));
112
115
mSecondaryColor = a .getColor (R .styleable .OtpEditText_oev_secondary_color , getResources ().getColor (R .color .light_gray ));
113
116
mTextColor = a .getColor (R .styleable .OtpEditText_oev_text_color , getResources ().getColor (android .R .color .black ));
117
+ mBoxStyle = a .getString (R .styleable .OtpEditText_oev_box_style );
118
+
119
+ if (mBoxStyle != null && !mBoxStyle .isEmpty ()) {
120
+ switch (mBoxStyle ) {
121
+ case UNDERLINE :
122
+ case ROUNDED_UNDERLINE :
123
+ mStrokePaint = new Paint (getPaint ());
124
+ mStrokePaint .setStrokeWidth (4 );
125
+ mStrokePaint .setStyle (Paint .Style .FILL );
126
+ break ;
127
+
128
+ case SQUARE_BOX :
129
+ case ROUNDED_BOX :
130
+ mStrokePaint = new Paint (getPaint ());
131
+ mStrokePaint .setStrokeWidth (4 );
132
+ mStrokePaint .setStyle (Paint .Style .STROKE );
133
+ break ;
134
+
135
+ default :
136
+ mStrokePaint = new Paint (getPaint ());
137
+ mStrokePaint .setStrokeWidth (4 );
138
+ mStrokePaint .setStyle (Paint .Style .FILL );
139
+
140
+ mBoxStyle = UNDERLINE ;
141
+ }
142
+ } else {
143
+ mStrokePaint = new Paint (getPaint ());
144
+ mStrokePaint .setStrokeWidth (4 );
145
+ mStrokePaint .setStyle (Paint .Style .FILL );
146
+
147
+ mBoxStyle = UNDERLINE ;
148
+ }
114
149
115
150
a .recycle ();
116
151
}
@@ -147,15 +182,34 @@ protected void onDraw(Canvas canvas) {
147
182
getPaint ().getTextWidths (getText (), 0 , textLength , textWidths );
148
183
149
184
for (int i = 0 ; i < mNumChars ; i ++) {
150
- updateColorForLines (i <= textLength , i == textLength , getText ().length (), (int ) mNumChars );
151
- canvas .drawLine (startX , bottom , startX + mCharSize , bottom , mLinesPaint );
152
-
153
- try {
154
- canvas .drawRoundRect (startX , top , startX + mCharSize , bottom , 8 , 8 , mLinesPaint );
155
- canvas .drawRoundRect (startX , top , startX + mCharSize , bottom , 8 , 8 , mStrokePaint );
156
- } catch (NoSuchMethodError err ) {
157
- canvas .drawRect (startX , top , startX + mCharSize , bottom , mLinesPaint );
158
- canvas .drawRect (startX , top , startX + mCharSize , bottom , mStrokePaint );
185
+ updateColorForLines (i <= textLength , i == textLength );
186
+
187
+ switch (mBoxStyle ) {
188
+ case ROUNDED_UNDERLINE :
189
+ try {
190
+ canvas .drawRoundRect (startX , bottom * .95f , startX + mCharSize , bottom , 16 , 16 , mStrokePaint );
191
+ } catch (NoSuchMethodError err ) {
192
+ canvas .drawRect (startX , bottom * .95f , startX + mCharSize , bottom , mStrokePaint );
193
+ }
194
+ break ;
195
+ case ROUNDED_BOX :
196
+ try {
197
+ canvas .drawRoundRect (startX , top , startX + mCharSize , bottom , 8 , 8 , mLinesPaint );
198
+ canvas .drawRoundRect (startX , top , startX + mCharSize , bottom , 8 , 8 , mStrokePaint );
199
+ } catch (NoSuchMethodError err ) {
200
+ canvas .drawRect (startX , top , startX + mCharSize , bottom , mLinesPaint );
201
+ canvas .drawRect (startX , top , startX + mCharSize , bottom , mStrokePaint );
202
+ }
203
+ break ;
204
+
205
+ case UNDERLINE :
206
+ canvas .drawRect (startX , ((float ) bottom * .95f ), startX + mCharSize , bottom , mStrokePaint );
207
+ break ;
208
+
209
+ case SQUARE_BOX :
210
+ canvas .drawRect (startX , top , startX + mCharSize , bottom , mLinesPaint );
211
+ canvas .drawRect (startX , top , startX + mCharSize , bottom , mStrokePaint );
212
+ break ;
159
213
}
160
214
if (getText ().length () > i ) {
161
215
float middle = startX + mCharSize / 2 ;
@@ -173,7 +227,7 @@ protected void onDraw(Canvas canvas) {
173
227
/**
174
228
* @param next Is the current char the next character to be input?
175
229
*/
176
- private void updateColorForLines (boolean next , boolean current , int textSize , int totalSize ) {
230
+ private void updateColorForLines (boolean next , boolean current ) {
177
231
if (next ) {
178
232
mStrokePaint .setColor (mSecondaryColor );
179
233
mLinesPaint .setColor (mSecondaryColor );
@@ -183,7 +237,7 @@ private void updateColorForLines(boolean next, boolean current, int textSize, in
183
237
}
184
238
if (current ) {
185
239
mLinesPaint .setColor (ContextCompat .getColor (getContext (), android .R .color .white ));
186
- mStrokePaint .setColor (mMainColor );
240
+ mStrokePaint .setColor (mPrimaryColor );
187
241
}
188
242
}
189
243
}
0 commit comments