88import android .content .Context ;
99import android .content .res .TypedArray ;
1010import android .graphics .Canvas ;
11- import android .graphics .Color ;
1211import android .graphics .Paint ;
1312import android .support .v4 .content .ContextCompat ;
1413import android .support .v7 .widget .AppCompatEditText ;
1514import android .text .Editable ;
16- import android .text .TextPaint ;
1715import android .util .AttributeSet ;
1816import android .view .ActionMode ;
1917import android .view .Menu ;
2321
2422public class OtpEditText extends AppCompatEditText {
2523 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 ;
3324
3425 private OnClickListener mClickListener ;
3526
36- private float mLineStroke = 1 ; //1dp by default
37- private float mLineStrokeSelected = 2 ; //2dp by default
3827 private Paint mLinesPaint ;
28+ private Paint mStrokePaint ;
3929
40- private int mMainColor ;
30+ private int defStyleAttr = 0 ;
31+ private int mMaxLength = 6 ;
32+ private int mPrimaryColor ;
4133 private int mSecondaryColor ;
4234 private int mTextColor ;
4335
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" ;
4549
4650 public OtpEditText (Context context ) {
4751 super (context );
@@ -65,11 +69,10 @@ private void init(Context context, AttributeSet attrs) {
6569 float multi = context .getResources ().getDisplayMetrics ().density ;
6670 mLineStroke = multi * mLineStroke ;
6771 mLineStrokeSelected = multi * mLineStrokeSelected ;
72+
6873 mLinesPaint = new Paint (getPaint ());
69- mStrokePaint = new Paint (getPaint ());
70- mStrokePaint .setStrokeWidth (4 );
71- mStrokePaint .setStyle (Paint .Style .STROKE );
7274 mLinesPaint .setStrokeWidth (mLineStroke );
75+
7376 setBackgroundResource (0 );
7477 mSpace = multi * mSpace ; //convert to pixels for our density
7578 mNumChars = mMaxLength ;
@@ -108,9 +111,41 @@ private void getAttrsFromTypedArray(AttributeSet attributeSet) {
108111 final TypedArray a = getContext ().obtainStyledAttributes (attributeSet , R .styleable .OtpEditText , defStyleAttr , 0 );
109112
110113 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 ));
112115 mSecondaryColor = a .getColor (R .styleable .OtpEditText_oev_secondary_color , getResources ().getColor (R .color .light_gray ));
113116 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 .STROKE );
139+
140+ mBoxStyle = ROUNDED_BOX ;
141+ }
142+ } else {
143+ mStrokePaint = new Paint (getPaint ());
144+ mStrokePaint .setStrokeWidth (4 );
145+ mStrokePaint .setStyle (Paint .Style .STROKE );
146+
147+ mBoxStyle = ROUNDED_BOX ;
148+ }
114149
115150 a .recycle ();
116151 }
@@ -147,15 +182,34 @@ protected void onDraw(Canvas canvas) {
147182 getPaint ().getTextWidths (getText (), 0 , textLength , textWidths );
148183
149184 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 ;
159213 }
160214 if (getText ().length () > i ) {
161215 float middle = startX + mCharSize / 2 ;
@@ -173,7 +227,7 @@ protected void onDraw(Canvas canvas) {
173227 /**
174228 * @param next Is the current char the next character to be input?
175229 */
176- private void updateColorForLines (boolean next , boolean current , int textSize , int totalSize ) {
230+ private void updateColorForLines (boolean next , boolean current ) {
177231 if (next ) {
178232 mStrokePaint .setColor (mSecondaryColor );
179233 mLinesPaint .setColor (mSecondaryColor );
@@ -183,7 +237,7 @@ private void updateColorForLines(boolean next, boolean current, int textSize, in
183237 }
184238 if (current ) {
185239 mLinesPaint .setColor (ContextCompat .getColor (getContext (), android .R .color .white ));
186- mStrokePaint .setColor (mMainColor );
240+ mStrokePaint .setColor (mPrimaryColor );
187241 }
188242 }
189243}
0 commit comments