本文为大家分享了Android实现通用验证码输入框的具体代码,供大家参考,具体内容如下
效果图
话不多说先上效果图,可以先先看看是不是自己想要的
闲聊
闲来无事优化项目时,发现原来的验证码输入框,可扩展性不高,就拿来优化了一下,说说我开始的的思路吧,最开始是想用自定义View实现的,但是发现各种画矩,太烦人了,最后采用的组合控件的形式,Android有现成的控件,用来组合组合就能用,为什么不用呢。
源码
xml ITEM 布局文件(view_auth_code_input_item.xml)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <? xml version = "1.0" encoding = "utf-8" ?> android:layout_width = "match_parent" android:layout_height = "match_parent" android:orientation = "vertical" > < TextView android:id = "@+id/number_tv" style = "@style/TextStyleMain" android:layout_width = "match_parent" android:layout_height = "0mm" android:layout_weight = "1" android:maxLength = "1" android:text = "0" android:textSize = "72mm" /> < View android:id = "@+id/split_v" android:layout_width = "match_parent" android:layout_height = "1mm" android:background = "@color/colorMain" /> </ LinearLayout > |
attrs 自定义属性(attrs.xml)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | <? xml version = "1.0" encoding = "utf-8" ?> < resources > <!-- 自定义验证码输入框 属性 --> < declare-styleable name = "AuthCodeInputView" > <!-- 当前输入位分割线颜色 --> < attr name = "currentSplitLineColor" format = "reference|color" /> <!-- 其他输入位分割线颜色 --> < attr name = "otherSplitLineColor" format = "reference|color" /> <!-- 分割线高度 --> < attr name = "splitLineHeight" format = "dimension" /> <!-- 验证码位数 --> < attr name = "digit" format = "integer" /> <!-- 单个验证码宽度 --> < attr name = "singleCaptchaWidth" format = "dimension" /> <!-- 验证码当前输入位字体颜色 --> < attr name = "currentTextColor" format = "reference|color" /> <!-- 验证码当前输入位字体大小 --> < attr name = "currentTextSize" format = "dimension" /> <!-- 验证码其他输入位字体颜色 --> < attr name = "otherTextColor" format = "reference|color" /> <!-- 验证码其它输入位字体大小 --> < attr name = "otherTextSize" format = "dimension" /> <!-- 默认颜色 --> < attr name = "defaultColor" format = "reference|color" /> <!-- 默认字体大小 --> < attr name = "defaultTextSize" format = "dimension" /> <!-- 默认间距 --> < attr name = "defaultSpacing" format = "dimension" /> </ declare-styleable > </ resources > |
组合控件(AuthCodeInputView.java)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | 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> * 自定义验证码输入框 * </pre> * </pre> */ public class AuthCodeInputView extends LinearLayout { // <!-- 默认间距 --> private int mDefaultSpacing = 16 ; // <!-- 默认颜色 --> @ColorInt private int mDefaultColor = Color.BLACK; // <!-- 默认字体大小 --> private int mDefaultTextSize = 36 ; // <!-- 当前输入位分割线颜色 --> @ColorInt private int mCurrentSplitLineColor = mDefaultColor; // <!-- 其他输入位分割线颜色 --> @ColorInt private int mOtherSplitLineColor = mDefaultColor; // <!-- 分割线高度 --> private int mSplitLineHeight = 1 ; // <!-- 验证码位数 --> private int mDigit = 4 ; // <!-- 单个验证码宽度 --> private int mSingleCaptchaWidth = 100 ; // <!-- 验证码当前输入位字体颜色 --> @ColorInt private int mCurrentTextColor = mDefaultColor; // <!-- 验证码当前输入位字体大小 --> private int mCurrentTextSize = mDefaultTextSize; // <!-- 验证码其他输入位字体颜色 --> @ColorInt private int mOtherTextColor = mDefaultColor; // <!-- 验证码其它输入位字体大小 --> private int mOtherTextSize = mDefaultTextSize; // 记录当前输入文本 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++) { // 实例化 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 ); // 分割线高度只在初始化时设置一次 View mSplitV = child.findViewById(R.id.split_v); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, mSplitLineHeight); mSplitV.setLayoutParams(params); addView(child); } } // 设置(未)选中属性 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); // 默认间距 mDefaultSpacing = ( int ) o.getDimension(R.styleable.AuthCodeInputView_defaultSpacing, 16f); // 获取默认颜色 mDefaultColor = o.getColor(R.styleable.AuthCodeInputView_defaultColor, Color.BLACK); // 获取默认字体大小 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; // 验证码位数 mDigit = o.getInteger(R.styleable.AuthCodeInputView_digit, 4 ); // 单个验证码宽度 mSingleCaptchaWidth = ( int ) o.getDimension(R.styleable.AuthCodeInputView_singleCaptchaWidth, 100f); // 验证码当前输入位字体颜色 mCurrentTextColor = o.getColor(R.styleable.AuthCodeInputView_currentTextColor, mDefaultColor); // 验证码当前输入位字体大小 mCurrentTextSize = ( int ) o.getDimension(R.styleable.AuthCodeInputView_currentTextSize , mDefaultTextSize); // 验证码其他输入位字体颜色 mOtherTextColor = o.getColor(R.styleable.AuthCodeInputView_otherTextColor, mDefaultColor); // 验证码其它输入位字体大小 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( "" ); } } // 设置文本 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; } } |
至于效果图下面那个安全键盘源码就太多了,我就不多了的,我这边是组合控件实现的,超简单。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持自学编程网。
- 本文固定链接: https://zxbcw.cn/post/204959/
- 转载请注明:必须在正文中标注并保留原文链接
- QQ群: PHP高手阵营官方总群(344148542)
- QQ群: Yii2.0开发(304864863)