Android 手机号344格式化,字符串拼接和EditText输入框

本文介绍了Android环境下,针对11位手机号的处理方式,包括EditText输入框的格式化设置,以及TextView中手机号文本的显示。通过setFormatRules(3, 4, 4)实现手机号的344格式化展示。" 136311958,7337247,AI在电商营销策略中的应用与算法解析,"['人工智能', '机器学习', '深度学习', '推荐系统', '数据挖掘']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        国内手机号一般11位数字,在登录注册等页面经常会用到,其他信息介绍页面也可能会用到手机号的显示。

场景如下图:

 

 

一、EditText输入框

使用:binding.phoneEditText.setFormatRules(3, 4, 4)

private const val TAG = 100010

/**
 * Set format rules
 *
 * @param array format rules array, if you want to format as 'xxx xxxx xxxx', pass 3, 4, 4.
 * @param formatChar format char, default is space.
 */
fun EditText.setFormatRules(vararg array: Int, formatChar: Char = ' ') {
    require(array.size > 1) { "Format array size must greater than 1." }
    var count = 0
    //间隔字符位置索引的集合
    val list = ArrayList<Int>(array.size - 1)
    array.forEachIndexed { index, item ->
        count += item
        if (index != array.lastIndex) {
            list.add(count + index)
        }
    }
    //11位数字+2位空格
    val maxLength = count + array.size - 1
    //从已经移出的FormatTextWatcher获取文本
    val oldText = textWithFormatRemoved
    //设置新的FormatTextWatcher
    setFormatTextWatcher(this, formatChar, list, maxLength)
    //过滤所有的非InputFilter.LengthFilter集合
    val filterList = this.filters.filter { it !is InputFilter.LengthFilter }
    //追加到末尾一个InputFilter.LengthFilter
    this.filters = Array(filterList.size + 1) {
        if (it < filterList.size) filterList[it] else InputFilter.LengthFilter(maxLength)
    }
    //设置旧的文本
    setText(oldText)
    //光标移动到最后一个位置
    setSelection(text.length)
}

/***
 * Get the text with format removed.
 */
val EditText.textWithFormatRemoved: String
    get() {
        val watcher = getTag(TAG) as? FormatTextWatcher
        return if (watcher == null) {
            text.toString()
        } else {
            text.toString().replace(watcher.formatChar.toString(), "")
        }
    }

/**
 * Set format edit listener.
 *
 * @param listener isComplete: is edit complete or not, text: text with format removed.
 */
fun EditText.setOnFormatEditListener(listener: (isComplete: Boolean, text: String) -> Unit) {
    val watcher = getTag(TAG) as? FormatTextWatcher
    require(watcher != null) { "You should call setFormatRules first." }
    watcher.onFormatEditListener = listener
}

/**
 * 设置格式化文本监听器
 *
 * @param et 输入框
 * @param formatChar 间隔字符,比如是空格
 * @param list 间隔字符位置索引的集合,比如是3,8
 * @param maxLength 整个文本的长度,比如是11+2=13
 */
private fun setFormatTextWatcher(
    et: EditText,
    formatChar: Char,
    list: List<Int>,
    maxLength: Int
) {
    //获取旧的FormatTextWatcher
    var watcher = et.getTag(TAG) as? FormatTextWatcher
    if (watcher == null) {
        watcher = FormatTextWatcher(et)
        et.tag = TAG
        et.addTextChangedListener(watcher)
    }
    //间隔字符
    watcher.formatChar = formatChar
    //设置新的『间隔字符位置索引的集合』
    watcher.formatCharIndexList.clear()
    watcher.formatCharIndexList.addAll(list)
    //设置文本长度
    watcher.maxLength = maxLength
}

class FormatTextWatcher(private val et: EditText) : TextWatcher {

    var formatChar: Char = ' '

    val formatCharIndexList = ArrayList<Int>()

    var maxLength = 0

    var onFormatEditListener: ((isComplete: Boolean, text: String) -> Unit)? = null

    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}

    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}

    override fun afterTextChanged(s: Editable?) {
        val value = s?.toString() ?: return
        if (value.isEmpty()) return
        //最后一个字符是『间隔字符』
        if (value.last() == formatChar) {
            //删除最后一个字符
            s.delete(value.lastIndex, value.lastIndex + 1)
            //更新选择的位置
            updateSelectionPosition(s)
            return
        }
        //遍历文本的每一个字符
        value.forEachIndexed { index, c ->
            //当前索引的在『间隔字符索引集合』里面
            if (formatCharIndexList.contains(index)) {
                //当前字符不是『间隔字符』,就需要替换成『间隔字符』
                if (c != formatChar) {
                    //保存原始filters
                    val filters = s.filters
                    //设置一个空数组filters
                    s.filters = emptyArray()
                    //替换成『间隔字符』
                    s.insert(index, formatChar.toString())
                    //还原filters
                    s.filters = filters
                    //更新选择的位置
                    updateSelectionPosition(s)
                    return
                }
            } else {
                //当前字符是『间隔字符』
                if (c == formatChar) {
                    //删除当前字符
                    s.delete(index, index + 1)
                    //更新选择的位置
                    updateSelectionPosition(s)
                    return
                }
            }
        }
        updateSelectionPosition(s)
        val isComplete = value.length == maxLength
        val text = value.replace(formatChar.toString(), "")
        onFormatEditListener?.invoke(isComplete, text)
    }

    /**
     * 更新选择位置
     */
    private fun updateSelectionPosition(s: Editable) {
        val index = et.selectionStart - 1
        s.toString().getOrNull(index)?.let {
            if (it == formatChar) {
                et.setSelection(index)
            }
        }
    }
/**
 * 处理手机号
 */
fun EditText.dealPhoneNumber(): String {
    val originAccount = text?.toString() ?: ""
    return originAccount.replace(" ", "")
}

 

二、TextView文本字符串

/**
 * 处理手机号格式按照 *** **** ****处理
 */
fun String.dealPhoneFormat(): String {
    val sb = StringBuilder()
    if (TextUtils.isEmpty(this)) {
        return ""
    }
    val inputNumber: String = replace(" ", "")
    var a = "" //存储第一段的三位数
    var b = "" //存储第二段的四位数
    var c = "" //存储第三段的四位数
    if (inputNumber.length >= 3) {
        a = inputNumber.substring(0, 3)
    } else if (inputNumber.length < 3) {
        a = inputNumber.substring(0, inputNumber.length)
    }
    if (inputNumber.length >= 7) {
        b = inputNumber.substring(3, 7)
        c = inputNumber.substring(7, inputNumber.length)
    } else if (inputNumber.length in 4..6) {
        b = inputNumber.substring(3, inputNumber.length)
    }
    if (a.isNotEmpty()) {
        sb.append(a)
        if (a.length == 3) {
            sb.append(" ")
        }
    }
    if (b.isNotEmpty()) {
        sb.append(b)
        if (b.length == 4) {
            sb.append(" ")
        }
    }
    if (c.isNotEmpty()) {
        sb.append(c)
    }
    return sb.toString()
}

三、Textview 文本字符串*隐藏

/**
 * 隐藏手机号中间的部分
 */
val String.hideMiddle: String
    get() {
        val split = split(" ").toMutableList()
        if (split.size > 1) {
            split[1] = "****"
        }
        return split.joinToString(separator = "")
    }
/**
 * 处理手机号格式按照 *** **** ****处理
 */
fun String.dealPhoneFormat(): String {
    val sb = StringBuilder()
    if (TextUtils.isEmpty(this)) {
        return ""
    }
    val inputNumber: String = replace(" ", "")
    var a = "" //存储第一段的三位数
    var b = "" //存储第二段的四位数
    var c = "" //存储第三段的四位数
    if (inputNumber.length >= 3) {
        a = inputNumber.substring(0, 3)
    } else if (inputNumber.length < 3) {
        a = inputNumber.substring(0, inputNumber.length)
    }
    if (inputNumber.length >= 7) {
        b = inputNumber.substring(3, 7)
        c = inputNumber.substring(7, inputNumber.length)
    } else if (inputNumber.length in 4..6) {
        b = inputNumber.substring(3, inputNumber.length)
    }
    if (a.isNotEmpty()) {
        sb.append(a)
        if (a.length == 3) {
            sb.append(" ")
        }
    }
    if (b.isNotEmpty()) {
        sb.append(b)
        if (b.length == 4) {
            sb.append(" ")
        }
    }
    if (c.isNotEmpty()) {
        sb.append(c)
    }
    return sb.toString()
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

艾阳Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值