本文为大家分享了Android实现通用验证码输入框的具体代码,供大家参考,具体内容如下

效果图

话不多说先上效果图,可以先先看看是不是自己想要的

闲聊

闲来无事优化项目时,发现原来的验证码输入框,可扩展性不高,就拿来优化了一下,说说我开始的的思路吧,最开始是想用自定义View实现的,但是发现各种画矩,太烦人了,最后采用的组合控件的形式,Android有现成的控件,用来组合组合就能用,为什么不用呢。

源码

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: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)

<?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)

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;
 }
}

至于效果图下面那个安全键盘源码就太多了,我就不多了的,我这边是组合控件实现的,超简单。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持Devmax。

Android自定义控件实现通用验证码输入框的更多相关文章

  1. 详解通过focusout事件解决IOS键盘收起时界面不归位的问题

    这篇文章主要介绍了详解通过focusout事件解决IOS键盘收起时界面不归位的问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  2. HTML5去掉输入框type为number时的上下箭头的实现方法

    这篇文章主要介绍了HTML5去掉输入框type为number时的上下箭头的实现方法,需要的朋友可以参考下

  3. html5 canvas合成海报所遇问题及解决方案总结

    这篇文章主要介绍了html5 canvas合成海报所遇问题及解决方案总结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  4. Html5 video标签视频的最佳实践

    这篇文章主要介绍了Html5 video标签视频的最佳实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  5. HTML5中input输入框默认提示文字向左向右移动的示例代码

    这篇文章主要介绍了HTML5中input输入框默认提示文字向左向右移动,本文通过实例代码给大家介绍的非常详细对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. 详解移动端HTML5页面端去掉input输入框的白色背景和边框(兼容Android和ios)

    本篇文章主要介绍了移动端HTML5页面端去掉input输入框的白色背景和边框,非常具有实用价值,需要的朋友可以参考下。

  7. HTML5在微信内置浏览器下右上角菜单的调整字体导致页面显示错乱的问题

    HTML5在微信内置浏览器下,在右上角菜单的调整字体导致页面显示错乱的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

  8. ios – containerURLForSecurityApplicationGroupIdentifier:在iPhone和Watch模拟器上给出不同的结果

    我使用默认的XCode模板创建了一个WatchKit应用程序.我向iOSTarget,WatchkitAppTarget和WatchkitAppExtensionTarget添加了应用程序组权利.(这是应用程序组名称:group.com.lombax.fiveminutes)然后,我尝试使用iOSApp和WatchKitExtension访问共享文件夹URL:延期:iOS应用:但是,测试NSURL

  9. Ionic – Splash Screen适用于iOS,但不适用于Android

    我有一个离子应用程序,其中使用CLI命令离子资源生成的启动画面和图标iOS版本与正在渲染的启动画面完美配合,但在Android版本中,只有在加载应用程序时才会显示白屏.我检查了config.xml文件,所有路径看起来都是正确的,生成的图像出现在相应的文件夹中.(我使用了splash.psd模板来生成它们.我错过了什么?这是config.xml文件供参考,我觉得我在这里做错了–解决方法在config.xml中添加以下键:它对我有用!

  10. ios – 无法启动iPhone模拟器

    /Library/Developer/CoreSimulator/Devices/530A44CB-5978-4926-9E91-E9DBD5BFB105/data/Containers/Bundle/Application/07612A5C-659D-4C04-ACD3-D211D2830E17/ProductName.app/ProductName然后,如果您在Xcode构建设置中选择标准体系结构并再次构建和运行,则会产生以下结果:dyld:lazysymbolbindingFailed:Symbol

随机推荐

  1. Flutter 网络请求框架封装详解

    这篇文章主要介绍了Flutter 网络请求框架封装详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. Android单选按钮RadioButton的使用详解

    今天小编就为大家分享一篇关于Android单选按钮RadioButton的使用详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

  3. 解决android studio 打包发现generate signed apk 消失不见问题

    这篇文章主要介绍了解决android studio 打包发现generate signed apk 消失不见问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

  4. Android 实现自定义圆形listview功能的实例代码

    这篇文章主要介绍了Android 实现自定义圆形listview功能的实例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  5. 详解Android studio 动态fragment的用法

    这篇文章主要介绍了Android studio 动态fragment的用法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. Android用RecyclerView实现图标拖拽排序以及增删管理

    这篇文章主要介绍了Android用RecyclerView实现图标拖拽排序以及增删管理的方法,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下

  7. Android notifyDataSetChanged() 动态更新ListView案例详解

    这篇文章主要介绍了Android notifyDataSetChanged() 动态更新ListView案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

  8. Android自定义View实现弹幕效果

    这篇文章主要为大家详细介绍了Android自定义View实现弹幕效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  9. Android自定义View实现跟随手指移动

    这篇文章主要为大家详细介绍了Android自定义View实现跟随手指移动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. Android实现多点触摸操作

    这篇文章主要介绍了Android实现多点触摸操作,实现图片的放大、缩小和旋转等处理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部