软件编程
位置:首页>> 软件编程>> Android编程>> Android自定义短信验证码组件

Android自定义短信验证码组件

作者:Unknown world  发布时间:2022-10-06 00:30:13 

标签:Android,短信,验证码

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

来源:https://blog.csdn.net/qq_36573702/article/details/113260144

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com