Android实现短信验证码输入框

本文实例为大家分享了Android实现短信验证码输入框的具体代码,供大家参考,具体内容如下
【Android实现短信验证码输入框】Android实现短信验证码输入框
文章图片

其实用官方自定的那个inputEditText默认带下划线的,然后自己再实行焦点和输入框弹出等操作也可以。
写这个自定义View主要是为了练习。

/** * 实现了粘贴事件监听回调的 EditText */open class ListenPasteEditTextTest : AppCompatEditText {constructor(context: Context): super(context)constructor(context: Context, attributeSet: AttributeSet): super(context,attributeSet)constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int): super(context, attributeSet, defStyleAttr)var lisenter: ClipInterface ? = nulloverride fun onTextContextMenuItem(id: Int): Boolean {when(id) {//剪切复制黏贴android.R.id.cut -> lisenter?.onCut(); android.R.id.copy -> lisenter?.onCopy(); android.R.id.paste -> lisenter?.onPaste(); }return super.onTextContextMenuItem(id)}}interface ClipInterface{fun onCut()fun onCopy()fun onPaste()}

/** * 手机验证码输入控件 */class VerificationCodeInputTest(context: Context, attributeSet: AttributeSet) : ViewGroup(context, attributeSet), ClipInterface{private val box = 4private val boxWidth = 120private val boxHeight = 120private var childPadding = 14private val TYPE_NUMBER = "number"private val TYPE_TEXT = "text"private val TYPE_PASSWORD = "password"private val TYPE_PHONE = "phone"private val boxBgFocus: Drawable? = nullprivate val boxBgNormal: Drawable? = nullprivate val inputType = TYPE_NUMBERvar listener: VerCideListener? = nullinit {val textWatcher = object : TextWatcher{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?) {if (s != null) {if (s.isNotEmpty()) {focus()checkAndCommit()}}}}val onKeyListener = OnKeyListener { v, keyCode, event ->if (keyCode == KeyEvent.KEYCODE_DEL) {//backFocus(); backFocusClearAll()}false}//四个输入框for (index in 0 until box) {val editText = ListenPasteEditTextTest(context)val layoutParams = LinearLayout.LayoutParams(boxWidth, boxHeight)layoutParams.bottomMargin = childPaddinglayoutParams.topMargin = childPaddinglayoutParams.leftMargin = childPaddinglayoutParams.rightMargin = childPaddinglayoutParams.gravity = Gravity.CENTEReditText.layoutParams = layoutParamseditText.lisenter = thiseditText.setOnKeyListener(onKeyListener)//设置背景颜色,就是输入框中的下划线setBg(editText, false)editText.setTextColor(Color.BLACK)editText.gravity = Gravity.CENTER//最多给你输入一个字符editText.filters = arrayOf(InputFilter.LengthFilter(1))//设置textView输入内容的显示模式if (TYPE_PASSWORD == inputType) {editText.transformationMethod = PasswordTransformationMethod.getInstance()} else if (TYPE_TEXT == inputType) {editText.inputType = InputType.TYPE_CLASS_TEXT} else if (TYPE_PHONE == inputType) {editText.inputType = InputType.TYPE_CLASS_PHONE}editText.id = index//设置字符宽度editText.setEms(1)editText.addTextChangedListener(textWatcher)addView(editText, index)}}override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {var parentWidth = measuredWidth//如果在xml中配置的是match_patent 则直接获取当前手机的width尺寸if (parentWidth == ViewGroup.LayoutParams.MATCH_PARENT) {parentWidth = getScreenWidth()}Log.d(javaClass.name, "onMeasure width $parentWidth")val count = childCountfor (i in 0 until count) {val child = getChildAt(i)this.measureChild(child, widthMeasureSpec, heightMeasureSpec)}if (count > 0) {val child = getChildAt(0)val cWidth = child.measuredWidthif (parentWidth != ViewGroup.LayoutParams.WRAP_CONTENT) {// 重新计算paddingchildPadding = (parentWidth - cWidth * count) / (count + 1)}val cHeight = child.measuredHeightval maxH = cHeight + 2 * childPaddingval maxW = cWidth * count + childPadding * (count + 1)//上面都是计算当前editText的width加上pandding,之后设置给父布局setMeasuredDimension(View.resolveSize(maxW, widthMeasureSpec),View.resolveSize(maxH, heightMeasureSpec))}}override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {val childCount = childCountfor (i in 0 until childCount) {val child = getChildAt(i)child.visibility = View.VISIBLEval cWidth = child.measuredWidthval cHeight = child.measuredHeightval cl = childPadding + i * (cWidth + childPadding)val cr = cl + cWidthval ct = childPaddingval cb = ct + cHeightchild.layout(cl, ct, cr, cb)}}private fun getScreenWidth(): Int {val resources = this.resourcesval dm = resources.displayMetricsreturn dm.widthPixels}override fun onCut() {}override fun onCopy() {}override fun onPaste() {val copyText = getCutAndCopyText()// 如果是数字并且 length 和 填写位数一致才会进行填充if (isNumeric(copyText) && copyText.length == box) {for (i in 0 until childCount) {(getChildAt(i) as EditText).append(copyText.get(i).toString())}}}fun setBg(editText: EditText, focus: Boolean) {if (boxBgNormal != null && !focus) {editText.background = boxBgNormal} else if (boxBgFocus != null && focus) {editText.background = boxBgFocus}}private fun focus() {val count = childCountvar editText: EditTextfor (i in 0 until count) {editText = getChildAt(i) as EditTextif (editText.text.isEmpty()) {editText.requestFocus()return}}}private fun checkAndCommit() {val stringBuilder = StringBuilder()var full = falsefor (i in 0 until box) {val editText = getChildAt(i) as EditTextval content = editText.text.toString()if (!content.isEmpty()) {stringBuilder.append(content)}}if (stringBuilder.length == box) {full = true}if (full) {if (listener != null) {listener?.onComplete(stringBuilder.toString())backFocusClearAll()}}}//清空所有并重新输入fun backFocusClearAll() {var editText: EditTextfor (i in 0 until box) {editText = getChildAt(i) as EditTexteditText.setText("")editText.clearFocus()}getChildAt(0).requestFocus()}/*** 判断是否是数字** @param str* @return*/private fun isNumeric(str: String?): Boolean {if (str == null || str.isEmpty()) {return false}for (i in 0 until str.length) {if (!Character.isDigit(str[i])) {return false}}return true}/*** 获取剪贴板内容*/private fun getCutAndCopyText(): String {val manager = context.getSystemService(CLIPBOARD_SERVICE) as ClipboardManagerif (manager != null && manager.hasPrimaryClip() && manager.primaryClip!!.itemCount > 0) {val addedText = manager.primaryClip!!.getItemAt(0).textif (addedText != null) {return addedText.toString()}}return ""}}interface VerCideListener {fun onComplete(content: String)}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    推荐阅读