溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Android中怎么自定義一個(gè)驗(yàn)證碼輸入框

發(fā)布時(shí)間:2021-06-26 16:40:15 來源:億速云 閱讀:181 作者:Leah 欄目:編程語言

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)碛嘘P(guān)Android中怎么自定義一個(gè)驗(yàn)證碼輸入框,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

xml布局:

<?xml version="1.0" encoding="utf-8"?><LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:orientation="vertical"  android:gravity="end"  > <TextView   android:id="@+id/tv_view_top_tip"   android:layout_width="match_parent"   android:layout_height="wrap_content"   android:layout_marginBottom="5dp"   android:textColor="@color/img_code_text_error_color"   android:textSize="12sp"   android:text="error"   /> <RelativeLayout   android:layout_width="match_parent"   android:layout_height="wrap_content">  <LinearLayout    android:id="@+id/ll_code"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:orientation="horizontal"    android:baselineAligned="false">   <LinearLayout     android:layout_width="0dp"     android:layout_height="wrap_content"     android:layout_weight="1"     android:orientation="vertical"     android:layout_marginRight="5dp">    <RelativeLayout      android:layout_width="match_parent"      android:layout_height="wrap_content"      android:layout_marginBottom="6dp"    >     <TextView       android:id="@+id/tv_code1"       android:layout_width="match_parent"       android:layout_height="wrap_content"       android:textColor="@color/global_text_color_10"       android:textSize="24sp"       android:textStyle="bold"       android:background="@null"       android:layout_centerInParent="true"       android:gravity="center"/>     <View       android:id="@+id/v1_center_line"       android:layout_width="1.5dp"       android:layout_height="16dp"       android:visibility="invisible"       android:layout_centerInParent="true"       android:background="@color/mainColor"       />    </RelativeLayout>     <View      android:id="@+id/v1"      android:layout_width="match_parent"      android:layout_height="1dp"      android:background="@color/mainColor" />   </LinearLayout>    <LinearLayout     android:layout_width="0dp"     android:layout_height="wrap_content"     android:layout_weight="1"     android:orientation="vertical"     android:layout_marginRight="5dp"     android:layout_marginLeft="5dp">    <RelativeLayout      android:layout_width="match_parent"      android:layout_height="wrap_content"      android:layout_marginBottom="6dp"    >     <TextView       android:id="@+id/tv_code2"       android:layout_width="match_parent"       android:layout_height="wrap_content"       android:textColor="@color/global_text_color_10"       android:textSize="24sp"       android:textStyle="bold"       android:background="@null"       android:layout_centerInParent="true"       android:gravity="center"/>     <View       android:id="@+id/v2_center_line"       android:layout_width="1.5dp"       android:layout_height="16dp"       android:visibility="invisible"       android:layout_centerInParent="true"       android:background="@color/mainColor" />    </RelativeLayout>     <View      android:id="@+id/v2"      android:layout_width="match_parent"      android:layout_height="1dp"      android:background="@color/global_text_color_grey" />   </LinearLayout>   <LinearLayout     android:layout_width="0dp"     android:layout_height="wrap_content"     android:layout_weight="1"     android:orientation="vertical"     android:layout_marginRight="5dp"     android:layout_marginLeft="5dp">    <RelativeLayout      android:layout_width="match_parent"      android:layout_height="wrap_content"      android:layout_marginBottom="6dp"    >     <TextView       android:id="@+id/tv_code3"       android:layout_width="match_parent"       android:layout_height="wrap_content"       android:textColor="@color/global_text_color_10"       android:textSize="24sp"       android:textStyle="bold"       android:background="@null"       android:layout_centerInParent="true"       android:gravity="center"/>     <View       android:id="@+id/v3_center_line"       android:layout_width="1.5dp"       android:layout_height="16dp"       android:visibility="invisible"       android:layout_centerInParent="true"       android:background="@color/mainColor"/>    </RelativeLayout>     <View      android:id="@+id/v3"      android:layout_width="match_parent"      android:layout_height="1dp"      android:background="@color/global_text_color_grey" />   </LinearLayout>   <LinearLayout     android:layout_width="0dp"     android:layout_height="wrap_content"     android:layout_weight="1"     android:orientation="vertical"     android:layout_marginRight="5dp"     android:layout_marginLeft="5dp">     <RelativeLayout      android:layout_width="match_parent"      android:layout_height="wrap_content"      android:layout_marginBottom="6dp"    >     <TextView       android:id="@+id/tv_code4"       android:layout_width="match_parent"       android:layout_height="wrap_content"       android:textColor="@color/global_text_color_10"       android:background="@null"       android:textStyle="bold"       android:textSize="24sp"       android:layout_centerInParent="true"       android:gravity="center"/>      <View       android:id="@+id/v4_center_line"       android:layout_width="1.5dp"       android:layout_height="16dp"       android:visibility="invisible"       android:layout_centerInParent="true"       android:background="@color/mainColor" />    </RelativeLayout>    <View      android:id="@+id/v4"      android:layout_width="match_parent"      android:layout_height="1dp"      android:background="@color/global_text_color_grey" />   </LinearLayout>   <LinearLayout     android:id="@+id/ll5_parent"     android:layout_width="0dp"     android:layout_height="wrap_content"     android:layout_weight="1"     android:orientation="vertical"     android:layout_marginRight="5dp"     android:layout_marginLeft="5dp">     <RelativeLayout      android:layout_width="match_parent"      android:layout_height="wrap_content"      android:layout_marginBottom="6dp"    >     <TextView       android:id="@+id/tv_code5"       android:layout_width="match_parent"       android:layout_height="wrap_content"       android:textColor="@color/global_text_color_10"       android:background="@null"       android:textStyle="bold"       android:textSize="24sp"       android:layout_centerInParent="true"       android:gravity="center"/>      <View       android:id="@+id/v5_center_line"       android:layout_width="1.5dp"       android:layout_height="16dp"       android:visibility="invisible"       android:layout_centerInParent="true"       android:background="@color/mainColor" />    </RelativeLayout>    <View      android:id="@+id/v5"      android:layout_width="match_parent"      android:layout_height="1dp"      android:background="@color/global_text_color_grey" />   </LinearLayout>   <LinearLayout     android:id="@+id/ll6_parent"     android:layout_width="0dp"     android:layout_height="wrap_content"     android:layout_weight="1"     android:orientation="vertical"     android:layout_marginLeft="5dp">     <RelativeLayout      android:layout_width="match_parent"      android:layout_height="wrap_content"      android:layout_marginBottom="6dp"    >     <TextView       android:id="@+id/tv_code6"       android:layout_width="match_parent"       android:layout_height="wrap_content"       android:textColor="@color/global_text_color_10"       android:background="@null"       android:textStyle="bold"       android:textSize="24sp"       android:layout_centerInParent="true"       android:gravity="center"/>      <View       android:id="@+id/v6_center_line"       android:layout_width="1.5dp"       android:layout_height="16dp"       android:visibility="invisible"       android:layout_centerInParent="true"       android:background="@color/mainColor" />    </RelativeLayout>    <View      android:id="@+id/v6"      android:layout_width="match_parent"      android:layout_height="1dp"      android:background="@color/global_text_color_grey" />   </LinearLayout>  </LinearLayout>   <EditText    android:id="@+id/et_code"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:layout_alignTop="@+id/ll_code"    android:layout_alignBottom="@+id/ll_code"    android:background="@android:color/transparent"    android:textColor="@android:color/transparent"    android:cursorVisible="false"    android:inputType="number"/> </RelativeLayout>  <TextView   android:id="@+id/tv_get_sms_code"   android:layout_width="wrap_content"   android:layout_height="wrap_content"   android:layout_marginTop="9.5dp"   android:paddingBottom="10dp"   android:textColor="@color/text_color_pressed_selector"   android:textSize="12sp"   android:text="@string/resend_verify_code" /> </LinearLayout>class CustomSmsCodeInputLayout : RelativeLayout, View.OnClickListener {  /**  * 枚舉中有兩種狀態(tài),F(xiàn)OUR四個(gè)輸入框,SIX6個(gè)輸入框  */ 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)    }   }  } }  /*啟動(dòng)計(jì)時(shí)器*/ fun startCountDownTimer() {  cancelCountDownTimer()  /*倒計(jì)時(shí)60秒,每次執(zhí)行間隔1秒*/  mCountDownTimerUtil = CountDownTimerUtil(mContext, tv_get_sms_code, 60000, 1000)  mCountDownTimerUtil?.start() }  /*上下文*/ private var mContext: Context /*存放驗(yàn)證碼集合*/ var codes: ArrayList<String>? = ArrayList() /*輸入相關(guān)管理器*/ 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() {  //驗(yàn)證碼輸入  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)      }     }     }   }  })  // 監(jiān)聽驗(yàn)證碼刪除按鍵  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)     //回退的時(shí)候如果頂部的提示語顯示則隱藏掉     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) }  /*控制可輸入的最大長(zhǎng)度*/ private fun regexMaxInputSize(editable: Editable, maxSize: Int) {  if (codes?.size!! < maxSize) {   // 過濾掉由空格鍵引起的字符串出現(xiàn)空長(zhǎng)串的問題,使用正則替換規(guī)則(\\s*)可以替換掉絕大多數(shù)空白字符或空格   codes?.add(editable.toString().replace(Regex("\\s*"), ""))   showCode()  } }  /**  * 顯示輸入的驗(yàn)證碼  */ 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()//設(shè)置高亮顏色  callBack()//回調(diào) }  /**  * 設(shè)置高亮顏色  */ 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()  } }  /**  * 回調(diào)  */ private fun callBack() {  if (onInputListener == null) {   return  }  if ((defaultInputNum == InputLineNum.FOUR && codes?.size == 4)   ||(defaultInputNum == InputLineNum.SIX && codes?.size == 6)) {   /*zi自動(dòng)收起軟鍵盤*/   dismissSoftInput()   onInputListener!!.onSuccess(getPhoneCode())  } else {   onInputListener!!.onInput()  } }  //定義回調(diào) interface OnInputListener {  fun onSuccess(code: String)  fun onInput() }  /**  * 顯示鍵盤  */ fun showSoftInput() {  //顯示軟鍵盤  if (imm != null && et_code != null) {   et_code.requestFocus() //需先獲得焦點(diǎn)才能主動(dòng)彈出軟鍵盤   et_code.postDelayed({ imm?.showSoftInput(et_code, InputMethodManager.SHOW_FORCED) }, 200)  } }  /**  * 英藏鍵盤  */ fun dismissSoftInput() {  et_code.requestFocus()  //某些情況下必須延遲一定時(shí)間在執(zhí)行,不然英藏不了  et_code.postDelayed({ imm?.hideSoftInputFromWindow(et_code.windowToken, 0) }, 200) //強(qiáng)制隱藏鍵盤 }  /**  * 獲得手機(jī)號(hào)驗(yàn)證碼  * @return 驗(yàn)證碼  */ 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 }  /*設(shè)置頂部提示是否顯示*/ fun setTopTipVisible(isVisible: Boolean){  tv_view_top_tip.visibility = if(isVisible) View.VISIBLE else View.INVISIBLE }  /*設(shè)置當(dāng)前項(xiàng)中間豎線是否顯示*/ fun setCurrentCenterLineVisible(isVisible: Boolean){  isVisibleCenterLine = isVisible  //顯示豎線的話默認(rèn)顯示出第一條  v1_center_line.visibility = if(isVisibleCenterLine) View.VISIBLE else View.INVISIBLE }  /*設(shè)置底部獲取短信按鈕是否顯示*/ fun setBottomSmsTvVisible(isVisible: Boolean){  tv_get_sms_code.visibility = if(isVisible) View.VISIBLE else View.GONE }  /*設(shè)置頂部提示字樣*/ fun setTopTipText(text: String){  tv_view_top_tip.text = text }  /*設(shè)置頂部提示字樣顏色*/ fun setTopTipTextColor(textColor: Int){  tv_view_top_tip.setTextColor(textColor) }  /*設(shè)置當(dāng)前指定項(xiàng)下環(huán)線顏色*/ fun setCurrentIndexLineColor(underlineColor: Int){  color_focus = underlineColor  v1.setBackgroundColor(color_focus) }  /*設(shè)置當(dāng)前指定項(xiàng)的中間線顏色*/ fun setCenterLineColor(centerLineColor: Int){  color_centerLine = centerLineColor  v1_center_line.setBackgroundColor(color_centerLine) }  /*設(shè)置不是當(dāng)前指定項(xiàng)下劃線顏色*/ fun setAnotherIndexLineColor(underlineColor: Int){  color_default = underlineColor }  /*設(shè)置頂部提示的字樣和顏色*/ 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 }  /*更新獲取短信按鈕狀態(tài)*/ fun updateGetSmsTvEnable(isEnable: Boolean){  tv_get_sms_code.isEnabled = isEnable  tv_get_sms_code.setTextColor(mContext.resources.getColor(R.color.global_text_color_6c)) }  /*需要展示的輸入框數(shù)量*/ 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   }  } }  /*關(guān)閉清除計(jì)時(shí)器*/ fun cancelCountDownTimer(){  if (mCountDownTimerUtil != null){   mCountDownTimerUtil?.cancel()   mCountDownTimerUtil = null  } }  /**清除所有輸入的值*/ fun clearAllInputValues(){  setTopTipVisible(false)  codes?.clear()  showCode() }  /**  * 獲取到驗(yàn)證碼進(jìn)行彈窗顯示  */ 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() }  /**  * 驗(yàn)證出錯(cuò)時(shí)抖動(dòng)輸入框提示  */ 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) // 同時(shí)執(zhí)行x、y軸的動(dòng)畫  animatorSet.interpolator = CycleInterpolator(2F)// 執(zhí)行2次  animatorSet.duration = 500 // 1秒后結(jié)束  animatorSet.doOnEnd {   clearAllInputValues()   animatorSet.cancel()  }  animatorSet.start() }  /*輸入框監(jiān)聽回調(diào)《供外部調(diào)用》*/ private var onInputListener: OnInputListener? = null fun setOnInputListener(onInputListener: OnInputListener) {  this.onInputListener = onInputListener }  /*獲取驗(yàn)證碼點(diǎn)擊回調(diào)《供外部調(diào)用》*/ private var onClickSmsCodeTvListener: OnClickListener? = null fun setOnClickSmsCodeTvListener(onClickSmsCodeTvListener: OnClickListener){  this.onClickSmsCodeTvListener = onClickSmsCodeTvListener } }

主要有兩種顯示樣式,在枚舉中定義了4個(gè)輸入框6個(gè)輸入框

基本調(diào)用代碼如下:

//ll_sms_input就是CustomSmsCodeInputLayoutll_sms_input.run {//里邊的配置可以自行選擇配置   setTopTipVisible(false)   setCurrentCenterLineVisible(true)   setBottomSmsTvVisible(true)   setShowInputNum(CustomSmsCodeInputLayout.InputLineNum.SIX)//這里加載的是六個(gè)輸入框   setCurrentIndexLineColor(resources.getColor(R.color.global_text_color_grey))   //設(shè)置輸入類型只能是數(shù)字   setInputType(InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_SIGNED)   showSoftInput()  }ll_sms_input.setOnInputListener()//做輸入完成后的監(jiān)聽ll_sms_input.setOnClickSmsCodeTvListener()//點(diǎn)擊重新獲取按鈕的監(jiān)聽

上述就是小編為大家分享的Android中怎么自定義一個(gè)驗(yàn)證碼輸入框了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI