这期内容当中小编将会给大家带来有关Android中怎么自定义一个验证码输入框,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
网站建设哪家好,找创新互联!专注于网页设计、网站建设、微信开发、小程序设计、集团企业网站建设等服务项目。为回馈新老客户创新互联还提供了宕昌免费建站欢迎大家使用!
xml布局:
class CustomSmsCodeInputLayout : RelativeLayout, View.OnClickListener { /** * 枚举中有两种状态,FOUR四个输入框,SIX6个输入框 */ 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() /*倒计时60秒,每次执行间隔1秒*/ 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)) { /*zi自动收起软键盘*/ 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) //强制隐藏键盘 } /** * 获得手机号验证码 * @return 验证码 */ 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就是CustomSmsCodeInputLayoutll_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中怎么自定义一个验证码输入框了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注创新互联行业资讯频道。
分享文章:Android中怎么自定义一个验证码输入框
本文链接:
http://6mz.cn/article/pigpjc.html