Edit text for OTP with Each letter in separate positions

后端 未结 19 1009
别跟我提以往
别跟我提以往 2020-12-13 00:25

I\'m working on a application which asks for OTP when user want to reset his password for which I need a text like the one in attached Image... What I thought to proceed wi

19条回答
  •  借酒劲吻你
    2020-12-13 00:54

    OtpEditText.java (Custom EditText):

    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.text.Editable;
    import android.util.AttributeSet;
    import android.view.ActionMode;
    import android.view.View;
    import androidx.appcompat.widget.AppCompatEditText;
    
    public class OtpEditText extends AppCompatEditText {
        private float mSpace = 24; //24 dp by default, space between the lines
        private float mNumChars = 4;
        private float mLineSpacing = 8; //8dp by default, height of the text from our lines
        private int mMaxLength = 4;
        private float mLineStroke = 2;
        private Paint mLinesPaint;
        private OnClickListener mClickListener;
    
        public OtpEditText(Context context) {
            super(context);
        }
    
        public OtpEditText(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(context, attrs);
        }
    
        public OtpEditText(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init(context, attrs);
        }
    
        private void init(Context context, AttributeSet attrs) {
            float multi = context.getResources().getDisplayMetrics().density;
            mLineStroke = multi * mLineStroke;
            mLinesPaint = new Paint(getPaint());
            mLinesPaint.setStrokeWidth(mLineStroke);
            mLinesPaint.setColor(getResources().getColor(R.color.colorPrimaryDark));
            setBackgroundResource(0);
            mSpace = multi * mSpace; //convert to pixels for our density
            mLineSpacing = multi * mLineSpacing; //convert to pixels for our density
            mNumChars = mMaxLength;
    
            super.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    // When tapped, move cursor to end of text.
                    setSelection(getText().length());
                    if (mClickListener != null) {
                        mClickListener.onClick(v);
                    }
                }
            });
        }
    
        @Override
        public void setOnClickListener(OnClickListener l) {
            mClickListener = l;
        }
    
        @Override
        public void setCustomSelectionActionModeCallback(ActionMode.Callback actionModeCallback) {
            throw new RuntimeException("setCustomSelectionActionModeCallback() not supported.");
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            int availableWidth = getWidth() - getPaddingRight() - getPaddingLeft();
            float mCharSize;
            if (mSpace < 0) {
                mCharSize = (availableWidth / (mNumChars * 2 - 1));
            } else {
                mCharSize = (availableWidth - (mSpace * (mNumChars - 1))) / mNumChars;
            }
    
            int startX = getPaddingLeft();
            int bottom = getHeight() - getPaddingBottom();
    
            //Text Width
            Editable text = getText();
            int textLength = text.length();
            float[] textWidths = new float[textLength];
            getPaint().getTextWidths(getText(), 0, textLength, textWidths);
    
            for (int i = 0; i < mNumChars; i++) {
                canvas.drawLine(startX, bottom, startX + mCharSize, bottom, mLinesPaint);
                if (getText().length() > i) {
                    float middle = startX + mCharSize / 2;
                    canvas.drawText(text, i, i + 1, middle - textWidths[0] / 2, bottom - mLineSpacing, getPaint());
                }
                if (mSpace < 0) {
                    startX += mCharSize * 2;
                } else {
                    startX += mCharSize + mSpace;
                }
            }
        }
    }
    

    Use this customised EditText in your XML like below:

    
    

    Reference:
    Article: https://medium.com/@ali.muzaffar/building-a-pinentryedittext-in-android-5f2eddcae5d3
    Sample Code: https://gist.github.com/alphamu/0d3055e0233c5749b8d6

提交回复
热议问题