这里提一下,这个当时也是在网上看到一个博主写的代码改了下用在我么项目中的验证码输入框。博主的地址不记得了这里只能顺带标注一下。。。
效果图如下:
就是这个酱紫
直入主题,代码如下:
xml布局:
class CustomSmsCodeInputLayout : RelativeLayout, View.onClickListener { enum class InputLineNum(var num: Int){ FOUR(4), SIX(6) } override fun onClick(v: View?) { when(v?.id){ R.id.tv_get_sms_code->{ clearAllInputValues() if (onClickSmsCodeTvListener != null) { onClickSmsCodeTvListener?.onClick(tv_get_sms_code) } } } } fun startCountDownTimer() { cancelCountDownTimer() mCountDownTimerUtil = CountDownTimerUtil(mContext, tv_get_sms_code, 60000, 1000) mCountDownTimerUtil?.start() } private var mContext: Context var codes: ArrayList ? = ArrayList() private var imm: InputMethodManager? = null private var color_default = Color.parseColor("#999999") private var color_focus = Color.parseColor("#FF9200") private var color_centerLine = Color.parseColor("#FF9200") private var isVisibleCenterLine = true private var defaultInputNum = InputLineNum.SIX private var mCountDownTimerUtil: CountDownTimerUtil? = null constructor(context: Context) : super(context){ mContext = context initView() } constructor(context: Context, attrs: AttributeSet) : super(context, attrs){ mContext = context initView() } private fun initView() { imm = mContext.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager? LayoutInflater.from(mContext).inflate(R.layout.view_sms_code_input_layout, this) initEvent() } private fun initEvent() { //验证码输入 et_code.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {} override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {} override fun afterTextChanged(editable: Editable?) { if (editable != null && editable.trim().isNotEmpty()) { // 每输入 et_code.setText("") when(defaultInputNum){ InputLineNum.FOUR -> { regexMaxInputSize(editable, InputLineNum.FOUR.num) } InputLineNum.SIX -> { regexMaxInputSize(editable, InputLineNum.SIX.num) } } } } }) // 监听验证码删除按键 et_code.setonKeyListener(object : View.onKeyListener { override fun onKey(view: View, keyCode: Int, keyEvent: KeyEvent): Boolean { if (keyCode == KeyEvent.KEYCODE_DEL && keyEvent.action == KeyEvent.ACTION_DOWN && codes?.size!! > 0) { codes!!.removeAt(codes?.size!! - 1) //回退的时候如果顶部的提示语显示则隐藏掉 if (tv_view_top_tip.visibility == View.VISIBLE){ tv_view_top_tip.visibility = View.INVISIBLE } showCode() return true } return false } }) tv_get_sms_code.setonClickListener(this) } private fun regexMaxInputSize(editable: Editable, maxSize: Int) { if (codes?.size!! < maxSize) { // 过滤掉由空格键引起的字符串出现空长串的问题,使用正则替换规则(\s*)可以替换掉绝大多数空白字符或空格 codes?.add(editable.toString().replace(Regex("\s*"), "")) showCode() } } private fun showCode() { var code1: String? = "" var code2: String? = "" var code3: String? = "" var code4: String? = "" var code5: String? = "" var code6: String? = "" if (codes?.size!! >= 1) { code1 = codes?.get(0) } if (codes?.size!! >= 2) { code2 = codes?.get(1) } if (codes?.size!! >= 3) { code3 = codes?.get(2) } if (codes?.size!! >= 4) { code4 = codes?.get(3) } if (codes?.size!! >= 5) { code5 = codes?.get(4) } if (codes?.size!! >= 6) { code6 = codes?.get(5) } tv_code1.text = code1 tv_code2.text = code2 tv_code3.text = code3 tv_code4.text = code4 tv_code5.text = code5 tv_code6.text = code6 setColor()//设置高亮颜色 callBack()//回调 } private fun setColor() { v1.setBackgroundColor(color_default) v2.setBackgroundColor(color_default) v3.setBackgroundColor(color_default) v4.setBackgroundColor(color_default) v5.setBackgroundColor(color_default) v6.setBackgroundColor(color_default) if (codes?.size == 0) { v1.setBackgroundColor(color_focus) updateCenterLineColor(v1_center_line) } if (codes?.size == 1) { v2.setBackgroundColor(color_focus) updateCenterLineColor(v2_center_line) } if (codes?.size == 2) { v3.setBackgroundColor(color_focus) updateCenterLineColor(v3_center_line) } if (codes?.size!! == 3) { v4.setBackgroundColor(color_focus) updateCenterLineColor(v4_center_line) } if (codes?.size == 4) { v5.setBackgroundColor(color_focus) updateCenterLineColor(v5_center_line) } if (codes?.size!! == 5) { v6.setBackgroundColor(color_focus) updateCenterLineColor(v6_center_line) } if ((defaultInputNum == InputLineNum.FOUR && codes?.size!! >= 4) || (defaultInputNum == InputLineNum.SIX && codes?.size!! >= 6)) { invisibleAllCenterLine() } } private fun callBack() { if (onInputListener == null) { return } if ((defaultInputNum == InputLineNum.FOUR && codes?.size == 4) ||(defaultInputNum == InputLineNum.SIX && codes?.size == 6)) { dismissSoftInput() onInputListener!!.onSuccess(getPhoneCode()) } else { onInputListener!!.onInput() } } //定义回调 interface onInputListener { fun onSuccess(code: String) fun onInput() } fun showSoftInput() { //显示软键盘 if (imm != null && et_code != null) { et_code.requestFocus() //需先获得焦点才能主动弹出软键盘 et_code.postDelayed({ imm?.showSoftInput(et_code, InputMethodManager.SHOW_FORCED) }, 200) } } fun dismissSoftInput() { et_code.requestFocus() //某些情况下必须延迟一定时间在执行,不然英藏不了 et_code.postDelayed({ imm?.hideSoftInputFromWindow(et_code.windowToken, 0) }, 200) //强制隐藏键盘 } fun getPhoneCode(): String { val sb = StringBuilder() return if (!codes!!.isEmpty()) { for (code in codes!!) { sb.append(code) } sb.toString() }else{ "" } } private fun updateCenterLineColor(view: View){ if (isVisibleCenterLine) { invisibleAllCenterLine() view.visibility = View.VISIBLE } } private fun invisibleAllCenterLine() { v1_center_line.visibility = View.INVISIBLE v2_center_line.visibility = View.INVISIBLE v3_center_line.visibility = View.INVISIBLE v4_center_line.visibility = View.INVISIBLE v5_center_line.visibility = View.INVISIBLE v6_center_line.visibility = View.INVISIBLE } fun setTopTipVisible(isVisible: Boolean){ tv_view_top_tip.visibility = if(isVisible) View.VISIBLE else View.INVISIBLE } fun setCurrentCenterLineVisible(isVisible: Boolean){ isVisibleCenterLine = isVisible //显示竖线的话默认显示出第一条 v1_center_line.visibility = if(isVisibleCenterLine) View.VISIBLE else View.INVISIBLE } fun setBottomSmsTvVisible(isVisible: Boolean){ tv_get_sms_code.visibility = if(isVisible) View.VISIBLE else View.GONE } fun setTopTipText(text: String){ tv_view_top_tip.text = text } fun setTopTipTextColor(textColor: Int){ tv_view_top_tip.setTextColor(textColor) } fun setCurrentIndexLineColor(underlineColor: Int){ color_focus = underlineColor v1.setBackgroundColor(color_focus) } fun setCenterLineColor(centerLineColor: Int){ color_centerLine = centerLineColor v1_center_line.setBackgroundColor(color_centerLine) } fun setAnotherIndexLineColor(underlineColor: Int){ color_default = underlineColor } fun setTopTextAndColor(text: String, textColor: Int){ tv_view_top_tip.text = text tv_view_top_tip.setTextColor(textColor) } fun setInputType(type: Int) { et_code?.inputType = type } fun updateGetSmsTvEnable(isEnable: Boolean){ tv_get_sms_code.isEnabled = isEnable tv_get_sms_code.setTextColor(mContext.resources.getColor(R.color.global_text_color_6c)) } fun setShowInputNum(num: InputLineNum){ defaultInputNum = num when(defaultInputNum){ InputLineNum.FOUR -> { ll5_parent.visibility = View.GONE ll6_parent.visibility = View.GONE } InputLineNum.SIX -> { ll5_parent.visibility = View.VISIBLE ll6_parent.visibility = View.VISIBLE } } } fun cancelCountDownTimer(){ if (mCountDownTimerUtil != null){ mCountDownTimerUtil?.cancel() mCountDownTimerUtil = null } } fun clearAllInputValues(){ setTopTipVisible(false) codes?.clear() showCode() } fun showSmsCodeDialogTip(msg: String, title: String){ val msgSplit = msg.toList() DialogCreator.createTitleDialog( mContext as Activity, title, msg, DialogViewInfo("知道了"){ _,_ -> codes?.clear() msgSplit.forEach { item -> codes?.add(item.toString()) } showCode() } ).subscribe() } fun startShakeTip(){ val animX = ObjectAnimator.ofFloat(this, "translationX", 0F, 5F, -10F, 0F) val animY = ObjectAnimator.ofFloat(this, "translationY", 0F, 5F, -10F, 0F) val animatorSet = AnimatorSet() animatorSet.playTogether(animX, animY) // 同时执行x、y轴的动画 animatorSet.interpolator = CycleInterpolator(2F)// 执行2次 animatorSet.duration = 500 // 1秒后结束 animatorSet.doonEnd { clearAllInputValues() animatorSet.cancel() } animatorSet.start() } private var onInputListener: OnInputListener? = null fun setonInputListener(onInputListener: OnInputListener) { this.onInputListener = onInputListener } private var onClickSmsCodeTvListener: OnClickListener? = null fun setonClickSmsCodeTvListener(onClickSmsCodeTvListener: OnClickListener){ this.onClickSmsCodeTvListener = onClickSmsCodeTvListener } }
主要有两种显示样式,在枚举中定义了4个输入框6个输入框
基本调用代码如下:
//ll_sms_input就是CustomSmsCodeInputLayout
ll_sms_input.run {
//里边的配置可以自行选择配置
setTopTipVisible(false)
setCurrentCenterLineVisible(true)
setBottomSmsTvVisible(true)
setShowInputNum(CustomSmsCodeInputLayout.InputLineNum.SIX)//这里加载的是六个输入框
setCurrentIndexLineColor(resources.getColor(R.color.global_text_color_grey))
//设置输入类型只能是数字
setInputType(InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_SIGNED)
showSoftInput()
}
ll_sms_input.setonInputListener()//做输入完成后的监听
ll_sms_input.setonClickSmsCodeTvListener()//点击重新获取按钮的监听
总结
以上所述是小编给大家介绍的Android实现自定义验证码输入框效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对考高分网网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!



