Format credit card in edit text in android

后端 未结 29 2058
耶瑟儿~
耶瑟儿~ 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:38

    None of above answers is perfect for me. I created one that solves the start-string/end-string/mid-string issues. Copy & Paste should also work fine. This supports Mastercard, Visa and Amex. You can change the separator. If you don't need payment method type just remove it. It is Kotlin though. The idea is simple. Everytime when text changed I remove all separators and re-added them base on the format. The solves the issue start-string/mid-string issues. Then the only problem is that you need to work out the the right text position after separators added.

    fun addCreditCardNumberTxtWatcher(et: EditText, separator: Char, paymentMethodType: PaymentMethodType): TextWatcher {
        val tw = object : TextWatcher {
            var mBlock = false
            override fun afterTextChanged(s: Editable) {
            }
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
                  Logger.d("_debug", "s: $s, start: $start, count: $count, after $after")
            }
            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                if (mBlock)
                    return
                var lastPos = et.selectionStart
                val oldStr = et.text.toString().replace(separator.toString(), "", false)
                var newFormattedStr = ""
                if (before > 0) {
                    if (lastPos > 0 && et.text.toString()[lastPos - 1] == separator) lastPos--
                }
                Logger.d("_debug", "lastPos: $lastPos, s: $s, start: $start, before: $before, count $count")
                mBlock = true
                oldStr.forEachIndexed { i, c ->
                    when (paymentMethodType) {
                        PaymentMethodType.MASTERCARD, PaymentMethodType.VISA -> {
                            if (i > 0 && i % 4 == 0) {
                                newFormattedStr += separator
                            }
                        }
                        PaymentMethodType.AMERICAN_EXPRESS -> {
                            if (i == 4 || i == 10 || i == 15) {
                                newFormattedStr += separator
                            }
                        }
                    }
                    newFormattedStr += c
                }
                et.setText(newFormattedStr)
                if (before == 0) {
                    if (et.text.toString()[lastPos - 1] == separator) lastPos++
                }
                et.setSelection(lastPos)
                mBlock = false
            }
        }
        et.addTextChangedListener(tw)
        return tw
    }
    

提交回复
热议问题