Format credit card in edit text in android

后端 未结 29 2030
耶瑟儿~
耶瑟儿~ 2020-11-30 19:18

How to make EditText accept input in format:

4digit 4digit 4digit 4digit 

I tried Custom format edit text input android to acc

29条回答
  •  南方客
    南方客 (楼主)
    2020-11-30 19:48

    After searching a lot and not getting any satisfactory answer to meet my needs, I ended up writing my own function.

    Here is an example to format entered credit card details based on the type of card being entered. Currently it takes care of Visa, MasterCard and American Express for the purpose of formatting.

        editTxtCardNumber.addTextChangedListener(new TextWatcher() {
    
            private boolean spaceDeleted;
    
            @Override
            public void onTextChanged(CharSequence s, int arg1, int arg2,
                    int arg3) {
    
            }
    
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                CharSequence charDeleted = s.subSequence(start, start + count);
                spaceDeleted = " ".equals(charDeleted.toString());
            }
    
            @Override
            public void afterTextChanged(Editable editable) {
    
                if(editTxtCardNumber.getText().length() > 0 && editTxtCardNumber.getText().charAt(0) == '3') {
                    editTxtCardNumber.setFilters(new InputFilter[] { new InputFilter.LengthFilter(Constants.MAX_LENGTH_CARD_NUMBER_AMEX) });
    
                    editTxtCardNumber.removeTextChangedListener(this);
                    int cursorPosition = editTxtCardNumber.getSelectionStart();
                    String withSpaces = formatTextAmEx(editable);
                    editTxtCardNumber.setText(withSpaces);
                    editTxtCardNumber.setSelection(cursorPosition + (withSpaces.length() - editable.length()));
    
                    if (spaceDeleted) {
                        editTxtCardNumber.setSelection(editTxtCardNumber.getSelectionStart() - 1);
                        spaceDeleted = false;
                    }
    
                    editTxtCardNumber.addTextChangedListener(this);
                } else if(editTxtCardNumber.getText().length() > 0 
                        && (editTxtCardNumber.getText().charAt(0) == '4' || editTxtCardNumber.getText().charAt(0) == '5')) {
                    editTxtCardNumber.setFilters(new InputFilter[] { new InputFilter.LengthFilter(Constants.MAX_LENGTH_CARD_NUMBER_VISA_MASTERCARD) });
    
                    editTxtCardNumber.removeTextChangedListener(this);
                    int cursorPosition = editTxtCardNumber.getSelectionStart();
                    String withSpaces = formatTextVisaMasterCard(editable);
                    editTxtCardNumber.setText(withSpaces);
                    editTxtCardNumber.setSelection(cursorPosition + (withSpaces.length() - editable.length()));
    
                    if (spaceDeleted) {
                        editTxtCardNumber.setSelection(editTxtCardNumber.getSelectionStart() - 1);
                        spaceDeleted = false;
                    }
    
                    editTxtCardNumber.addTextChangedListener(this);
                } else {
                    editTxtCardNumber.setFilters(new InputFilter[] { new InputFilter.LengthFilter(Constants.MAX_LENGTH_CARD_NUMBER_VISA_MASTERCARD) });
    
                    editTxtCardNumber.removeTextChangedListener(this);
                    int cursorPosition = editTxtCardNumber.getSelectionStart();
                    String withSpaces = formatTextVisaMasterCard(editable);
                    editTxtCardNumber.setText(withSpaces);
                    editTxtCardNumber.setSelection(cursorPosition + (withSpaces.length() - editable.length()));
    
                    if (spaceDeleted) {
                        editTxtCardNumber.setSelection(editTxtCardNumber.getSelectionStart() - 1);
                        spaceDeleted = false;
                    }
    
                    editTxtCardNumber.addTextChangedListener(this);
                }
            }
        });
    
        private String formatTextVisaMasterCard(CharSequence text)
        {
            StringBuilder formatted = new StringBuilder();
            int count = 0;
            for (int i = 0; i < text.length(); ++i)
            {
                if (Character.isDigit(text.charAt(i)))
                {
                    if (count % 4 == 0 && count > 0)
                        formatted.append(" ");
                    formatted.append(text.charAt(i));
                    ++count;
                }
            }
            return formatted.toString();
        }
    
        private String formatTextAmEx(CharSequence text)
        {
            StringBuilder formatted = new StringBuilder();
            int count = 0;
            for (int i = 0; i < text.length(); ++i)
            {
                if (Character.isDigit(text.charAt(i)))
                {
                    if (count > 0 && ((count == 4) || (count == 10))) {
                        formatted.append(" ");
                    }
                    formatted.append(text.charAt(i));
                    ++count;
                }
            }
            return formatted.toString();
        }
    

    Other than formatting spaces, I also applied checks to make sure that card number doesn't exceed their maximum limit and user gets notified that he has entered all the digits by performing a change in font when the maximum limit is reached. Here is the function to perform the above mentioned operation.

    public void checkCardNoEnteredCorrectly() {
    if(editTxtCardNumber.getText().length() > 0 && editTxtCardNumber.getText().charAt(0) == '3') {
        if(editTxtCardNumber.getText().length() == Constants.MAX_LENGTH_CARD_NUMBER_AMEX) {
            editTxtCardNumber.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.amex), null, null, null);
        } else {
            editTxtCardNumber.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.amex), null, null, null);
        }
    } else if(editTxtCardNumber.getText().length() > 0 && editTxtCardNumber.getText().charAt(0) == '4') {
        if(editTxtCardNumber.getText().length() == Constants.MAX_LENGTH_CARD_NUMBER_VISA_MASTERCARD) {
            editTxtCardNumber.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.visa), null, null, null);
        } else {
            editTxtCardNumber.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.visa), null, null, null);
        }
    } else if(editTxtCardNumber.getText().length() > 0 && editTxtCardNumber.getText().charAt(0) == '5') {
        if(editTxtCardNumber.getText().length() == Constants.MAX_LENGTH_CARD_NUMBER_VISA_MASTERCARD) {
            editTxtCardNumber.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.master_card), null, null, null);
        } else {
            editTxtCardNumber.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.master_card), null, null, null);
        }
    } else {
        editTxtCardNumber.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.credit_card_number), null, null, null);
    }
    

    }

    Note: The declarations made in Constants.java is as follows:

    public static final int MAX_LENGTH_CARD_NUMBER_VISA_MASTERCARD = 19;
    public static final int MAX_LENGTH_CARD_NUMBER_AMEX = 17;
    

    Hope it helps!

提交回复
热议问题