您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關Android中怎么自定義一個驗證碼輸入框,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
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 { /** * 枚舉中有兩種狀態,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<String>? = 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中怎么自定義一個驗證碼輸入框了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。