InputFilter 和inputType属性 ——Edittext(二)

简介

Android开发中,输入框Edittext,经常会遇到控制输入类型,比如只输入数字,十进制,输入金额(两位小数 )等等。

  • Edittext inputType属性提供了一些规则,可以满足大部分的需求
  • InputFilter 可以自定义更复杂的输入规则

一、 inputType

    //输入类型为没有指定明确的类型的特殊内容类型
    android:inputType="none"

    //输入类型为普通文本
    android:inputType="text"

     //输入类型为数字文本
     android:inputType="number"

    //输入类型为电话号码
     android:inputType="phone"

    //输入类型为日期和时间
     android:inputType="datetime"

     //输入类型为{@link#TYPE_CLASS_DATETIME}的缺省变化值,只允许输入一个日期。
     android:inputType="date"

     //输入类型为{@link#TYPE_CLASS_DATETIME}的缺省变化值,只允许输入一个时间。
     android:inputType="time"

    //输入类型为小数数字,允许十进制小数点提供分数值。
     android:inputType="numberDecimal"

    //输入类型为数字是带符号的,允许在开头带正号或者负号
     android:inputType="numberSigned"

    //输入类型为数字密码
     android:inputType="numberPassword"

    //输入类型为自动完成文本类型
     android:inputType="textAutoComplete"

    //输入类型为自动纠正文本类型
     android:inputType="textAutoCorrect"

    //输入类型为所有字符大写
     android:inputType="textCapCharacters"

    //输入类型为每句的第一个字符大写
     android:inputType="textCapSentences"

    //输入类型为每个单词的第一个字母大写
     android:inputType="textCapWords"

    //输入法多行文本
     android:inputType="textImeMultiLine"

    //进行输入时,输入法无提示
     android:inputType="textNoSuggestions"

     //输入一个短的,可能是非正式的消息,如即时消息或短信。
     android:inputType="textShortMessage"

    //输入长内容,可能是正式的消息内容,比如电子邮件的主体
     android:inputType="textLongMessage"

    //输入文本以过滤列表等内容
     android:inputType="textFilter"

    //输入一个电子邮件地址
     android:inputType="textEmailAddress"

    //输入电子邮件主题行
     android:inputType="textEmailSubject"

    //输入一个密码
     android:inputType="textPassword"

    //输入对用户可见的密码
     android:inputType="textVisiblePassword"

    //输入人的姓名
     android:inputType="textPersonName"

    //输入邮寄地址
     android:inputType="textPostalAddress"

    //输入语音发音输入文本,如联系人拼音名称字段
     android:inputType="textPhonetic"

    //输入URI
     android:inputType="textUri"

    //输入网页表单中的文本
     android:inputType="textWebEditText"

    //输入网页表单中的邮件地址
     android:inputType="textWebEmailAddress"

    //输入网页表单中的密码
     android:inputType="textWebPassword"

二、InputFilter

InputFilter是系统提供的一个接口,里面只有一个方法filter(),用于过滤输入/插入的字符串,返回值为CharSequence。

/******************************* 输入框关联 *********************************/
et02.setFilters(filter);

/**********************************调用**************************************/

    private InputFilter[] filter = new InputFilter[] {

            new InputFilter() {
                /**
                 * @param source 输入的文字
                 * @param start 输入-0,删除-0
                 * @param end   输入-文字的长度,删除-0
                 * @param dest   原先显示的内容
                 * @param dstart 输入-原光标位置,删除-光标删除结束位置
                 * @param dend   输入-原光标位置,删除-光标删除开始位置
                 * @return
                 */
                @Override
                public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
                    System.out.println("source  =="+ source+"  start====="+start+"   end======"+end+"   dest===="+dest+"  dstart==="+dstart+"  dend=="+dend);
                    return null;
                }
            }
    };
/*******************************输入********************************/
09-09 09:30:18.977 10843-10843/zp.example.zptext I/System.out: source  ==我  start=====0   end======1   dest====  dstart===0  dend==0
09-09 09:30:21.873 10843-10843/zp.example.zptext I/System.out: source  ==喜欢  start=====0   end======2   dest====我  dstart===1  dend==1
09-09 09:30:26.817 10843-10843/zp.example.zptext I/System.out: source  ==湖畔  start=====0   end======2   dest====我喜欢  dstart===3  dend==3
09-09 09:31:10.265 10843-10843/zp.example.zptext I/System.out: source  ==的  start=====0   end======1   dest====我喜欢湖畔  dstart===5  dend==5

/************************************删除*****************************/
09-09 09:33:08.089 10843-10843/zp.example.zptext I/System.out: source  ==  start=====0   end======0   dest====我喜欢湖畔的  dstart===5  dend==6
09-09 09:33:22.341 10843-10843/zp.example.zptext I/System.out: source  ==  start=====0   end======0   dest====我喜欢湖畔  dstart===4  dend==5
09-09 09:33:27.733 10843-10843/zp.example.zptext I/System.out: source  ==  start=====0   end======0   dest====我喜欢湖  dstart===3  dend==4
09-09 09:33:30.269 10843-10843/zp.example.zptext I/System.out: source  ==  start=====0   end======0   dest====我喜欢  dstart===2  dend==3
09-09 09:33:31.485 10843-10843/zp.example.zptext I/System.out: source  ==  start=====0   end======0   dest====我喜  dstart===1  dend==2
09-09 09:33:32.777 10843-10843/zp.example.zptext I/System.out: source  ==  start=====0   end======0   dest====我  dstart===0  dend==1

金额过滤规则

下面这是一个输入金额的过滤规则
1、只能输入数字
2、首位不能是小数点
3、首位是0,第二位只能输入小数点
4、只允许输入两位小数

这段代码和网上的金额过滤规则有些区别,网上大部分输入金额的过滤规则,如果第一位是0,把光标移动到0前面,无法输入数字

class CashierInputFilter : InputFilter {

    //只允许出现数字和小数点
    var mPattern = Pattern.compile("([0-9]|\\.)*")


    /**
     * @param source    新输入的字符串
     * @param start     新输入的字符串起始下标,一般为0
     * @param end       新输入的字符串终点下标,一般为source长度-1
     * @param dest      输入之前文本框内容
     * @param dstart    原内容起始坐标,一般为0
     * @param dend      原内容终点坐标,一般为dest长度-1
     * @return          输入内容
     */
    override fun filter(
        source: CharSequence,
        start: Int,
        end: Int,
        dest: Spanned,
        dstart: Int,
        dend: Int
    ): CharSequence {
        val sourceText = source.toString()
        val destText = dest.toString()

        //验证删除等按键
        if (TextUtils.isEmpty(sourceText)) {
            return ""
        }

        val matcher = mPattern.matcher(source)
        //已经输入小数点的情况下,只能输入数字
        if (destText.contains(POINTER)) {
            if (!matcher.matches()) {
                return ""
            } else {
                if (POINTER == source.toString()) {  //只能输入一个小数点
                    return ""
                }
            }

            //验证小数点精度,保证小数点后只能输入两位
            val index = destText.indexOf(POINTER)
            val length = dend - index

            if (length > POINTER_LENGTH) {
                return ""
            }
        } else {
            /**
             * 没有输入小数点的情况下,只能输入小数点和数字
             * 1. 首位不能输入小数点
             * 2. 如果首位输入0,则接下来只能输入小数点了
             */
            if (!matcher.matches()) {
                return ""
            } else {
                if (POINTER == source.toString() && TextUtils.isEmpty(destText)) {  //首位不能输入小数点
                    return ""
                }
                else if (POINTER != source.toString() && ZERO == destText && dstart == 1) { //如果首位输入0,接下来只能输入小数点。可以在0之前继续输入数字
                    return ""
                }
            }
        }

        //验证输入金额的大小
        val sumText = (destText + sourceText).toDouble()
        return if (sumText > MAX_VALUE) {
            dest.subSequence(dstart, dend)
        } else dest.subSequence(dstart, dend).toString() + sourceText

    }

    companion object {

        //输入的最大金额
        private val MAX_VALUE = Integer.MAX_VALUE
        //小数点后的位数
        private val POINTER_LENGTH = 2

        private val POINTER = "."

        private val ZERO = "0"
    }
}

参考:

Android之设置EditText输入类型(setInputType()方法和android:inputType属性)
Android 实现EditText输入金额
Android 字符串过滤器InputFilter详解

©️2020 CSDN 皮肤主题: 撸撸猫 设计师:设计师小姐姐 返回首页