Phone number formatting an EditText in Android

前端 未结 14 917
情深已故
情深已故 2020-12-02 12:03

I am making a simple Address Book app (targeting 4.2) that takes name, address, city, state, zip and phone.

I want to format the phone number input as a phone number

14条回答
  •  醉梦人生
    2020-12-02 12:32

    You can use spawns to format phone numbers in Android. This solution is better than the others because it does not change input text. Formatting remains purely visual.

    implementation 'com.googlecode.libphonenumber:libphonenumber:7.0.4'
    

    Formatter class:

    open class PhoneNumberFormatter : TransformationMethod {
    private val mFormatter: AsYouTypeFormatter = PhoneNumberUtil.getInstance().getAsYouTypeFormatter(Locale.getDefault().country)
    
    override fun getTransformation(source: CharSequence, view: View): CharSequence {
        val formatted = format(source)
        if (source is Spannable) {
            setSpans(source, formatted)
            return source
        }
        return formatted
    }
    override fun onFocusChanged(view: View?, sourceText: CharSequence?, focused: Boolean, direction: Int, previouslyFocusedRect: Rect?) = Unit
    
    private fun setSpans(spannable: Spannable, formatted: CharSequence): CharSequence {
    
        spannable.clearSpawns()
    
        var charterIndex = 0
        var formattedIndex = 0
        var spawn = ""
        val spawns: List = spannable
            .map {
                spawn = ""
                charterIndex = formatted.indexOf(it, formattedIndex)
                if (charterIndex != -1){
                    spawn = formatted.substring(formattedIndex, charterIndex-1)
                    formattedIndex = charterIndex+1
                }
                spawn
            }
    
        spawns.forEachIndexed { index, sequence ->
            spannable.setSpan(CharterSpan(sequence), index, index + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
        }
    
        return formatted
    }
    
    private fun Spannable.clearSpawns() =
        this
            .getSpans(0, this.length, CharterSpan::class.java)
            .forEach { this.removeSpan(it) }
    
    private fun format(spannable: CharSequence): String {
        mFormatter.clear()
        var formated = ""
        for (i in 0 until spannable.length) {
            formated = mFormatter.inputDigit(spannable[i])
        }
        return formated
    }
    
    private inner class CharterSpan(private val charters: String) : ReplacementSpan() {
    
        var space = 0
    
        override fun getSize(paint: Paint, text: CharSequence, start: Int, end: Int, fm: Paint.FontMetricsInt?): Int {
            space = Math.round(paint.measureText(charters, 0, charters.length))
            return Math.round(paint.measureText(text, start, end)) + space
        }
    
        override fun draw(canvas: Canvas, text: CharSequence, start: Int, end: Int, x: Float, top: Int, y: Int, bottom: Int, paint: Paint) {
            space = Math.round(paint.measureText(charters, 0, charters.length))
            canvas.drawText(text, start, end, x + space, y.toFloat(), paint)
            canvas.drawText(charters, x, y.toFloat(), paint)
        }
        }
    
    }
    

    Uasge:

    editText.transformationMethod = formatter
    

提交回复
热议问题