Android自定義控件實(shí)現(xiàn)通用驗(yàn)證碼輸入框
本文為大家分享了Android實(shí)現(xiàn)通用驗(yàn)證碼輸入框的具體代碼,供大家參考,具體內(nèi)容如下
效果圖
話不多說先上效果圖,可以先先看看是不是自己想要的


閑聊
閑來無事優(yōu)化項(xiàng)目時(shí),發(fā)現(xiàn)原來的驗(yàn)證碼輸入框,可擴(kuò)展性不高,就拿來優(yōu)化了一下,說說我開始的的思路吧,最開始是想用自定義View實(shí)現(xiàn)的,但是發(fā)現(xiàn)各種畫矩,太煩人了,最后采用的組合控件的形式,Android有現(xiàn)成的控件,用來組合組合就能用,為什么不用呢。
源碼
xml ITEM 布局文件(view_auth_code_input_item.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='match_parent' android:orientation='vertical'> <TextView android: android:layout_width='match_parent' android:layout_height='0mm' android:layout_weight='1' android:maxLength='1' android:text='0' android:textSize='72mm' /> <View android: android:layout_width='match_parent' android:layout_height='1mm' android:background='@color/colorMain' /></LinearLayout>
attrs 自定義屬性(attrs.xml)
<?xml version='1.0' encoding='utf-8'?><resources> <!-- 自定義驗(yàn)證碼輸入框 屬性 --> <declare-styleable name='AuthCodeInputView'> <!-- 當(dāng)前輸入位分割線顏色 --> <attr name='currentSplitLineColor' format='reference|color' /> <!-- 其他輸入位分割線顏色 --> <attr name='otherSplitLineColor' format='reference|color' /> <!-- 分割線高度 --> <attr name='splitLineHeight' format='dimension' /> <!-- 驗(yàn)證碼位數(shù) --> <attr name='digit' format='integer' /> <!-- 單個(gè)驗(yàn)證碼寬度 --> <attr name='singleCaptchaWidth' format='dimension' /> <!-- 驗(yàn)證碼當(dāng)前輸入位字體顏色 --> <attr name='currentTextColor' format='reference|color' /> <!-- 驗(yàn)證碼當(dāng)前輸入位字體大小 --> <attr name='currentTextSize' format='dimension' /> <!-- 驗(yàn)證碼其他輸入位字體顏色 --> <attr name='otherTextColor' format='reference|color' /> <!-- 驗(yàn)證碼其它輸入位字體大小 --> <attr name='otherTextSize' format='dimension' /> <!-- 默認(rèn)顏色 --> <attr name='defaultColor' format='reference|color' /> <!-- 默認(rèn)字體大小 --> <attr name='defaultTextSize' format='dimension' /> <!-- 默認(rèn)間距 --> <attr name='defaultSpacing' format='dimension' /> </declare-styleable></resources>
組合控件(AuthCodeInputView.java)
import android.content.Context;import android.content.res.TypedArray;import android.graphics.Color;import android.os.Build;import android.text.TextUtils;import android.util.AttributeSet;import android.util.TypedValue;import android.view.Gravity;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.LinearLayout;import android.widget.TextView;import androidx.annotation.ColorInt;import androidx.annotation.RequiresApi;/** * <pre> * <b>author</b> :BraveTou * <b>blog</b> :https://blog.csdn.net/bravetou * <b>time</b> :2020/9/4 16:43 * <b>desc</b> :<pre> * 自定義驗(yàn)證碼輸入框 * </pre> * </pre> */public class AuthCodeInputView extends LinearLayout { // <!-- 默認(rèn)間距 --> private int mDefaultSpacing = 16; // <!-- 默認(rèn)顏色 --> @ColorInt private int mDefaultColor = Color.BLACK; // <!-- 默認(rèn)字體大小 --> private int mDefaultTextSize = 36; // <!-- 當(dāng)前輸入位分割線顏色 --> @ColorInt private int mCurrentSplitLineColor = mDefaultColor; // <!-- 其他輸入位分割線顏色 --> @ColorInt private int mOtherSplitLineColor = mDefaultColor; // <!-- 分割線高度 --> private int mSplitLineHeight = 1; // <!-- 驗(yàn)證碼位數(shù) --> private int mDigit = 4; // <!-- 單個(gè)驗(yàn)證碼寬度 --> private int mSingleCaptchaWidth = 100; // <!-- 驗(yàn)證碼當(dāng)前輸入位字體顏色 --> @ColorInt private int mCurrentTextColor = mDefaultColor; // <!-- 驗(yàn)證碼當(dāng)前輸入位字體大小 --> private int mCurrentTextSize = mDefaultTextSize; // <!-- 驗(yàn)證碼其他輸入位字體顏色 --> @ColorInt private int mOtherTextColor = mDefaultColor; // <!-- 驗(yàn)證碼其它輸入位字體大小 --> private int mOtherTextSize = mDefaultTextSize; // 記錄當(dāng)前輸入文本 private String mText = ''; public AuthCodeInputView(Context context) { super(context); init(context, null); } public AuthCodeInputView(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } public AuthCodeInputView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context, attrs); } @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public AuthCodeInputView(Context context, AttributeSet attrs, int defStyleAttr,int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); init(context, attrs); } // 初始化 private void init(Context context, AttributeSet attrs) { setOrientation(LinearLayout.HORIZONTAL); setGravity(Gravity.CENTER); if (getChildCount() > 0) { removeAllViews(); } initAttrs(context, attrs); if (mDigit <= 0) { return; } for (int i = 0; i < mDigit; i++) { // 實(shí)例化 ITEM 組件 View child = LayoutInflater.from(context).inflate( R.layout.view_auth_code_input_item, this, false); LayoutParams lp = new LayoutParams(mSingleCaptchaWidth, ViewGroup.LayoutParams.MATCH_PARENT); if (i != 0) { lp.leftMargin = mDefaultSpacing; } child.setLayoutParams(lp); setViewAttrs(child, null, false); // 分割線高度只在初始化時(shí)設(shè)置一次 View mSplitV = child.findViewById(R.id.split_v); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, mSplitLineHeight); mSplitV.setLayoutParams(params); addView(child); } } // 設(shè)置(未)選中屬性 private void setViewAttrs(View child, String text, boolean isSelected) { TextView mNumberTv = child.findViewById(R.id.number_tv); View mSplitV = child.findViewById(R.id.split_v); if (isSelected) { mNumberTv.setTextColor(mCurrentTextColor); mNumberTv.setTextSize(TypedValue.COMPLEX_UNIT_PX, mCurrentTextSize); mSplitV.setBackgroundColor(mCurrentSplitLineColor); } else { mNumberTv.setTextColor(mOtherTextColor); mNumberTv.setTextSize(TypedValue.COMPLEX_UNIT_PX, mOtherTextSize); mSplitV.setBackgroundColor(mOtherSplitLineColor); } mNumberTv.setText(TextUtils.isEmpty(text) ? '' : text); } // 初始化屬性 private void initAttrs(Context context, AttributeSet attrs) { if (null != attrs) { // AttributeSet 屬性值的索引 TypedArray o = context.obtainStyledAttributes(attrs, R.styleable.AuthCodeInputView); // 默認(rèn)間距 mDefaultSpacing = (int) o.getDimension(R.styleable.AuthCodeInputView_defaultSpacing, 16f); // 獲取默認(rèn)顏色 mDefaultColor = o.getColor(R.styleable.AuthCodeInputView_defaultColor, Color.BLACK); // 獲取默認(rèn)字體大小 mDefaultTextSize = (int) o.getDimension(R.styleable.AuthCodeInputView_defaultTextSize , 36f); // 輸入位分割線顏色 mCurrentSplitLineColor = o.getColor(R.styleable.AuthCodeInputView_currentSplitLineColor, mDefaultColor); // 其他輸入位分割線顏色 mOtherSplitLineColor = o.getColor(R.styleable.AuthCodeInputView_otherSplitLineColor, mDefaultColor); // 分割線高度 mSplitLineHeight = (int) o.getDimension(R.styleable.AuthCodeInputView_splitLineHeight , 1f); mSplitLineHeight = mSplitLineHeight <= 1 ? 1 : mSplitLineHeight; // 驗(yàn)證碼位數(shù) mDigit = o.getInteger(R.styleable.AuthCodeInputView_digit, 4); // 單個(gè)驗(yàn)證碼寬度 mSingleCaptchaWidth = (int) o.getDimension(R.styleable.AuthCodeInputView_singleCaptchaWidth, 100f); // 驗(yàn)證碼當(dāng)前輸入位字體顏色 mCurrentTextColor = o.getColor(R.styleable.AuthCodeInputView_currentTextColor, mDefaultColor); // 驗(yàn)證碼當(dāng)前輸入位字體大小 mCurrentTextSize = (int) o.getDimension(R.styleable.AuthCodeInputView_currentTextSize , mDefaultTextSize); // 驗(yàn)證碼其他輸入位字體顏色 mOtherTextColor = o.getColor(R.styleable.AuthCodeInputView_otherTextColor, mDefaultColor); // 驗(yàn)證碼其它輸入位字體大小 mOtherTextSize = (int) o.getDimension(R.styleable.AuthCodeInputView_otherTextSize, mDefaultTextSize); // 回收資源 o.recycle(); } } // 追加文本 public void addText(String text) { text = TextUtils.isEmpty(text) ? '' : text; setText(mText + text); } // 刪除文本 public void delText() { int count = TextUtils.isEmpty(mText) ? 0 : mText.length(); if (count > 0) { setText(mText.substring(0, count - 1)); } else { setText(''); } } // 設(shè)置文本 public void setText(String text) { text = text.trim(); int length = TextUtils.isEmpty(text) ? 0 : text.length(); if (length > mDigit) { this.mText = text.substring(0, mDigit); length = mDigit; } else { this.mText = length > 0 ? text : ''; } int count = getChildCount(); for (int i = 0; i < count; i++) { View child = getChildAt(i); if (i + 1 < length) { setViewAttrs(child, String.valueOf(text.charAt(i)), false); } else if (i + 1 == length) { setViewAttrs(child, String.valueOf(text.charAt(i)), true); } else { setViewAttrs(child, null, false); } } } // 獲取文本 public String getText() { return mText; }}
至于效果圖下面那個(gè)安全鍵盤源碼就太多了,我就不多了的,我這邊是組合控件實(shí)現(xiàn)的,超簡單。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持好吧啦網(wǎng)。
相關(guān)文章:
1. 詳解Android studio 動(dòng)態(tài)fragment的用法2. 解決Android studio xml界面無法預(yù)覽問題3. 圖文詳解vue中proto文件的函數(shù)調(diào)用4. Spring Boot和Thymeleaf整合結(jié)合JPA實(shí)現(xiàn)分頁效果(實(shí)例代碼)5. php模擬實(shí)現(xiàn)斗地主發(fā)牌6. 什么是python的自省7. Vue封裝一個(gè)TodoList的案例與瀏覽器本地緩存的應(yīng)用實(shí)現(xiàn)8. vue 使用localstorage實(shí)現(xiàn)面包屑的操作9. .Net Core使用Coravel實(shí)現(xiàn)任務(wù)調(diào)度的完整步驟10. Vuex localStorage的具體使用

網(wǎng)公網(wǎng)安備