Android自定义短信验证码组件

Android自定义短信验证码组件,供大家参考,具体内容如下

效果图

1.布局实现

因为要禁用光标,所以我用TextView代替了EditText,每一行显示的验证码个数由用户决定,所以我这里用线性布局的权重,对TextView进行控制宽度等分,然后设置选中和未选中当前TextView的底部边框,设置高亮颜色背景

2.接受用户输入

我这里使用了TextView,但是怎么接受用户输入的值呢。这里我直接继承了RelativeLayout,然后添加了一个透明的EditText,覆盖在这几个TextView上面,用户就可以点击唤起键盘输入

3.TextView如何显示值和删除值

我这里设置EditText的TextColor和BackgroundColor为Color.TRANSPARENT 透明,然后监听EditText的addTextChangedListener事件和setOnKeyListener按键删除事件,然后把值添加到TextView上,就能实现了,然后在写一个对外的接口。获取到输入的验证码。

4.添加闪烁的动画

我这里使用了ObjectAnimator,初始化给每个TextView添加动画,然后在输入的时候给当前的TextView启动动画,取消其他TextView动画

具体源码如下:

/**
 * @author wu_ming_zhi_bei
 * @date 2021/1/27 15:00
 * @Notes
 */
public class VerificationCodeView extends RelativeLayout {
  private Context mContext;
  private RelativeLayout.LayoutParams layoutParams;
  private int num = 4;//验证码数量
  private int codeSize;//字体大小
  private int codeColor;//字体颜色
  private List<TextView> tvs = new ArrayList<>();
  private List<String> codes = new ArrayList<>();
  private EditText etCode;
  private InputMethodManager imm;
  List<ObjectAnimator> animators = new ArrayList<>();

  public VerificationCodeView(Context context) {
    this(context,null);
  }

  public VerificationCodeView(Context context, AttributeSet attrs) {
    this(context,attrs,0);
  }

  public VerificationCodeView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init(context,attrs);
  }

  private void init(Context context, AttributeSet attrs) {
    this.mContext = context;
    imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);

    TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.VerificationCodeView);
    num = a.getInteger(R.styleable.VerificationCodeView_num,4);
    codeSize = a.getDimensionPixelSize(R.styleable.VerificationCodeView_codeSize,18);
    codeColor = a.getColor(R.styleable.VerificationCodeView_codeColor,getResources().getColor(R.color.theme_color));
    //初始化一个大的LinearLayout来存放验证码
    LinearLayout codeBox = new LinearLayout(mContext);
    codeBox.setOrientation(LinearLayout.HORIZONTAL);
    codeBox.setGravity(Gravity.CENTER);
    //添加方块
    for(int i=0;i<num;i++){
      TextView tv = new TextView(mContext);
      tv.setTextSize(codeSize);
      tv.setTextColor(codeColor);
      tv.setGravity(Gravity.CENTER);
      tv.setPadding(0,0,0,10);
      LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(
          LayoutParams.MATCH_PARENT,
          LayoutParams.MATCH_PARENT, 1);
      param.gravity = Gravity.CENTER;
      param.rightMargin = 20;
      param.leftMargin = 20;
      param.topMargin = 20;
      param.bottomMargin = 20;
      tv.setLayoutParams(param);
      //默认第一个选中
      if(i==0){
        tv.setText("|");
        tv.setBackground(mContext.getResources().getDrawable(R.drawable.code_border_current_bottom));
      }else{
        tv.setBackground(mContext.getResources().getDrawable(R.drawable.code_border_bottom));
      }
      codeBox.addView(tv);
      tvs.add(tv);//添加到数组
    }
    layoutParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    //添加codebox的位置在组件的最上面
    layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP,TRUE);
    layoutParams.setMargins(60,0,60,0);
    codeBox.setLayoutParams(layoutParams);

    //添加Edit
    etCode = new EditText(mContext);
    etCode.setLayoutParams(layoutParams);
    etCode.setLines(1);
    etCode.setMaxLines(1);
    etCode.setTextColor(Color.TRANSPARENT);
    etCode.setBackgroundColor(Color.TRANSPARENT);
    etCode.setCursorVisible(false);
    //添加edit监听
    etCode.addTextChangedListener(new TextWatcher() {
      @Override
      public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

      }

      @Override
      public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

      }

      @Override
      public void afterTextChanged(Editable editable) {
        if(editable != null && editable.length()>0) {
          etCode.setText("");//清空数据
          if(codes.size() < num){
            codes.add(editable.toString());
            showCode();
          }
        }
      }
    });

    // 监听验证码删除按键
    etCode.setOnKeyListener(new View.OnKeyListener() {
      @Override
      public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
        if (keyCode == KeyEvent.KEYCODE_DEL && keyEvent.getAction() == KeyEvent.ACTION_DOWN && codes.size()>0) {
          codes.remove(codes.size()-1);
          showCode();
          return true;
        }
        return false;
      }
    });
    addView(codeBox);
    addView(etCode);
    addAnimation();//添加东安湖
    setTwinkle();//开启动画
  }

  //显示验证码
  private void showCode(){
    int size = codes.size();//1 6
    for(int i=0;i<num;i++){
      if(size>i){
        tvs.get(i).setText(codes.get(i));//添加到textview
      }else if(size==i){
        tvs.get(i).setText("|");
      }else{
        tvs.get(i).setText("");
      }
    }
    etCode.setFocusable(true);
    etCode.requestFocus();
    etCode.setFocusableInTouchMode(true);
    etCode.requestFocusFromTouch();
    setTwinkle();//动画
    callBack();//回调

  }

  private void showColor(){
    int size = codes.size();
    if(size==0){
      tvs.get(0).setBackground(mContext.getResources().getDrawable(R.drawable.code_border_current_bottom));
    }else{
      for(int i=0;i<tvs.size();i++){
        if(i==size-1){
          tvs.get(i).setBackground(mContext.getResources().getDrawable(R.drawable.code_border_current_bottom));
        }else{
          tvs.get(i).setBackground(mContext.getResources().getDrawable(R.drawable.code_border_bottom));
        }
      }
    }
  }

  /**
   * 回调
   */
  private void callBack(){
    if(onInputListener==null){
      return;
    }
    if(codes.size()==num){
      onInputListener.onSucess(getPhoneCode());
    }else{
      onInputListener.onInput();
    }
  }

  //定义回调
  public interface OnInputListener{
    void onSucess(String code);
    void onInput();
  }
  private OnInputListener onInputListener;
  public void setOnInputListener(OnInputListener onInputListener){
    this.onInputListener = onInputListener;
  }

  /**
   * 获得手机号验证码
   * @return 验证码
   */
  public String getPhoneCode(){
    StringBuilder sb = new StringBuilder();
    for (String code : codes) {
      sb.append(code);
    }
    return sb.toString();
  }

  /**
   * 显示键盘
   */
  public void showSoftInput(){
    //显示软键盘
    if(imm!=null && etCode!=null) {
      etCode.postDelayed(new Runnable() {
        @Override
        public void run() {
          imm.showSoftInput(etCode, 0);
        }
      },200);
    }
  }

  /**
   * 隐藏键盘
   */
  public void hideSoftInput(){
    //显示软键盘
    if(imm!=null && etCode!=null) {
      etCode.postDelayed(new Runnable() {
        @Override
        public void run() {
          imm.hideSoftInputFromWindow(etCode.getWindowToken(), 0);
        }
      },200);
    }
  }

  /**
   * 添加动画
   */
  private void addAnimation(){
    for(int i=0;i<tvs.size();i++){
      ObjectAnimator animator = ObjectAnimator.ofInt(tvs.get(i), "TextColor", 0x00000000, 0xfff00000);
      animator.setDuration(10000);
      final int index = i;
      animator.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animator) {

        }

        @Override
        public void onAnimationEnd(Animator animator) {

        }

        @Override
        public void onAnimationCancel(Animator animator) {
          tvs.get(index).setTextColor(codeColor);
        }

        @Override
        public void onAnimationRepeat(Animator animator) {

        }
      });
      animator.setInterpolator(new LinearInterpolator());
      animator.setRepeatCount(Animation.INFINITE);
      animators.add(animator);
    }
  }

  /**
   * 开启动画
   */
  private void setTwinkle(){
    int size = codes.size();
    for(int i=0;i<tvs.size();i++){
      if(i==size){
        animators.get(i).start();
        tvs.get(i).setBackground(mContext.getResources().getDrawable(R.drawable.code_border_current_bottom));
      }else{
        animators.get(i).cancel();
        tvs.get(i).setBackground(mContext.getResources().getDrawable(R.drawable.code_border_bottom));
      }
    }
  }

  @Override
  protected void onDetachedFromWindow() {
    super.onDetachedFromWindow();
    for(int i=0;i<tvs.size();i++){
      animators.get(i).cancel();
    }
  }
}

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

(0)

相关推荐

  • Android如何通过手机自动获取短信验证码

    本文实例为大家分享了Android实现手机自动获取短信验证码功能,供大家参考,具体内容如下 1.短信监听广播 2.读取短信内容 3.截取短信内容[可以 reg截取] 4.填写至相应控件 PS:DevStore测试没有获取到验证码 源码片段 public class MainActivity extends Activity { private BroadcastReceiver smsReceiver; private IntentFilter filter2; private Handler

  • Android实现短信验证码获取自动填写功能(详细版)

    现在的应用在注册登录或者修改密码中都用到了短信验证码,那在android中是如何实现获取短信验证码并自动填写的呢? 首先,需要要在manifest中注册接收和读取短信的权限: <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission> <uses-permission android:name="android.permission.READ_

  • Android实现短信验证码自动填写功能

    本实例为大家分享了Android实现短信验证码自动填写功能,供大家参考,具体内容如下 实现思路很简单: 1.在需要输入验证码的Activity代码注册监听短信的广播 2.拦截短信,获取其中的验证码 3.回写到EditText private SmsReciver smsReciver = new SmsReciver(); /** 收到短信Action **/ String ACTION_SMS_RECIVER = "android.provider.Telephony.SMS_RECEIVED

  • Android获取和读取短信验证码的实现方法

    现如今,验证码在Android的客户端还是非常普遍的.通过手机账号和验证码直接去注册应用账户的信息.很多应用都以这种方式来完成注册.简单的介绍一下吧. Android获取短信验证码还是比较简单的,通过Mob官网提供的ShareSDK,调用其中内部的方法,就可以获取到短信的验证码了.提供一下Mob的官网地址.http://www.mob.com/#/在官网上注册相关的信息之后,下载相关的jar包和.so文件就可以实现获取短信验证码了(2.0之前的版本都需要下载jar包和 .so文件,而现在的2.2

  • Android获取短信验证码的实现方法

    先给大家展示下效果图,如果感觉不错,请参考实现思路详解 Android开发中关于短息验证码的设计层出不穷,越来越多的应用为了更好的提高软件的安全性,开始使用通过服务器向用户发送验证码的方式,来保护用户个人信息的安全性.无论是用户注册时的信息验证还是当用户发出找回密码请求时的短信验证,他们的工作原理大致上是一致的,因为项目的需要研究了一下关于这方面的知识,本篇我将带领大家一起实现这一当下流行的设计方案. 众所周知,短信验证需要服务器端生成一个验证码,然后发送到用户输入的手机上,这个过程需要服务器主

  • Android用 Mob 实现发送短信验证码实例

    和室友参加的互联网大赛要做一个 APP,涉及到用户的登录注册,于是上网找了许多资料,其中有阿里大于,网易云等等,阿里大于的客服给我说他们不支持 Android,网易云还要拍手持身份证的照片,而且这两个都收费,还麻烦,于是找了一个既简单有免费的,叫做 Mob,官网如下 Mob 官网 官方文档看了很多,还是觉得写的不好,于是自己写一篇. 注册账号 在 Mob 官网右上角点击注册,依次填入信息,其中公司一栏可以随便填 添加应用 登录后,点击 SecurityCodeSDK - 立即使用,Mob 会提示

  • Android实现自动提取短信验证码功能

    本文实例讲解了Android自动提取短信验证码解决方案,分享给大家供大家参考,具体内容如下 主要功能及优点 1.收到验证码短信后,自动提取短信中的验证码填写到相应输入框 2.可指定一个号码,只读取与他有关短信,避免提取来源错误 3.利用正则表达式,可匹配各种类型验证码 模块集成关键步骤     将auto_getcode_demo中src包里的SMSContentObserver类复制到你的项目src包中 在SMSContentObserver中:    修改正则表达式内容来匹配自己想要获取的字

  • Android开发工程中集成mob短信验证码功能的方法

    一.前言 现在的app基本上都需要用到短信功能,注册时或者有消息通知时需要给用户发送一条短信,但是对于个人开发者来说,去买第三方的短信服务实在是有点奢侈,很好的是mob为我们提供了免费的短信验证码服务功能,我不是打广告,的确觉得这项服务很不错.那么下面就简单讲一下如何在自己的工程里集成mob的短信功能,其实整个流程并不复杂,只是个人觉得mob的官方文档有点小乱,官方Demo也有点小复杂,同时有一些细节地方容易被忽视,也会导致一些问题. PS:太喜欢mob的logo了. 二.实现过程 本篇只涉及A

  • Android中用Bmob实现短信验证码功能的方法详解

    这篇文章主要介绍发送验证码和校验验证码的功能,用到一个第三方平台Bmob,那Bmob是什么呢?Bmob可以开发一个云存储的移动应用软件,他提供了大量的标准的API接口,根据需要接入相关服务,开发者可以更加专注于应用的开发,让产品交付更快速,验证码功能就是其中一个. 一.跟其他第三方一样,我们开发之前要做一些准备工作. 1.首先,去官网注册一个帐号:http://www.bmob.cn/: 2.然后就可以创建应用了:具体怎么做Bmob说得很清楚了(官方操作介绍),如果你不想看,我简单说一下:点击右

  • Android开发中通过手机号+短信验证码登录的实例代码

    首先,需要一个电话号码,目前很多账户都是将账户名设置成手机号,然后点击按钮获取手机验证码. 其次,你需要后台给你手机短信的验证接口,各个公司用的不一样,这个身为前端,不需要你来考虑,你只要让你后台给你写好接口,你直接调用就好了. activity_login.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.andr

随机推荐