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

}

}

}

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

以上是 Android自定义短信验证码组件 的全部内容, 来源链接: utcz.com/p/243248.html

回到顶部