Android自定義短信驗(yàn)證碼組件
Android自定義短信驗(yàn)證碼組件,供大家參考,具體內(nèi)容如下
效果圖

1.布局實(shí)現(xiàn)
因?yàn)橐霉鈽?biāo),所以我用TextView代替了EditText,每一行顯示的驗(yàn)證碼個數(shù)由用戶決定,所以我這里用線性布局的權(quán)重,對TextView進(jìn)行控制寬度等分,然后設(shè)置選中和未選中當(dāng)前TextView的底部邊框,設(shè)置高亮顏色背景
2.接受用戶輸入
我這里使用了TextView,但是怎么接受用戶輸入的值呢。這里我直接繼承了RelativeLayout,然后添加了一個透明的EditText,覆蓋在這幾個TextView上面,用戶就可以點(diǎn)擊喚起鍵盤輸入
3.TextView如何顯示值和刪除值
我這里設(shè)置EditText的TextColor和BackgroundColor為Color.TRANSPARENT 透明,然后監(jiān)聽EditText的addTextChangedListener事件和setOnKeyListener按鍵刪除事件,然后把值添加到TextView上,就能實(shí)現(xiàn)了,然后在寫一個對外的接口。獲取到輸入的驗(yàn)證碼。
4.添加閃爍的動畫
我這里使用了ObjectAnimator,初始化給每個TextView添加動畫,然后在輸入的時候給當(dāng)前的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;//驗(yàn)證碼數(shù)量
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來存放驗(yàn)證碼
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);
//默認(rèn)第一個選中
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);//添加到數(shù)組
}
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監(jiān)聽
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("");//清空數(shù)據(jù)
if(codes.size() < num){
codes.add(editable.toString());
showCode();
}
}
}
});
// 監(jiān)聽驗(yàn)證碼刪除按鍵
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();//添加?xùn)|安湖
setTwinkle();//開啟動畫
}
//顯示驗(yàn)證碼
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();//回調(diào)
}
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));
}
}
}
}
/**
* 回調(diào)
*/
private void callBack(){
if(onInputListener==null){
return;
}
if(codes.size()==num){
onInputListener.onSucess(getPhoneCode());
}else{
onInputListener.onInput();
}
}
//定義回調(diào)
public interface OnInputListener{
void onSucess(String code);
void onInput();
}
private OnInputListener onInputListener;
public void setOnInputListener(OnInputListener onInputListener){
this.onInputListener = onInputListener;
}
/**
* 獲得手機(jī)號驗(yàn)證碼
* @return 驗(yàn)證碼
*/
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();
}
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android開發(fā)中通過手機(jī)號+短信驗(yàn)證碼登錄的實(shí)例代碼
- Android開發(fā)工程中集成mob短信驗(yàn)證碼功能的方法
- Android實(shí)現(xiàn)短信驗(yàn)證碼獲取自動填寫功能(詳細(xì)版)
- Android獲取和讀取短信驗(yàn)證碼的實(shí)現(xiàn)方法
- Android實(shí)現(xiàn)自動提取短信驗(yàn)證碼功能
- Android實(shí)現(xiàn)短信驗(yàn)證碼自動填寫功能
- Android獲取短信驗(yàn)證碼的實(shí)現(xiàn)方法
- Android用 Mob 實(shí)現(xiàn)發(fā)送短信驗(yàn)證碼實(shí)例
- Android如何通過手機(jī)自動獲取短信驗(yàn)證碼
- Android中用Bmob實(shí)現(xiàn)短信驗(yàn)證碼功能的方法詳解
相關(guān)文章
Android 解決使用SearchView時軟鍵盤不支持actionSearch的問題
本文主要介紹使用SearchView時軟鍵盤不支持actionSearch,這里提供了解決方案,希望能幫助開發(fā)Android應(yīng)用的同學(xué)2016-07-07
Android開發(fā)中Activity屬性設(shè)置小結(jié)
Android應(yīng)用開發(fā)中會經(jīng)常遇到Activity組件的使用,下面就來講解下Activity組件。Activity的生命周期、通信方式和IntentFilter等內(nèi)容,并提供了一些日常開發(fā)中經(jīng)常用到的關(guān)于Activity的技巧和方法。通過本文,你可以進(jìn)一步了接Android中Activity的運(yùn)作方式。2015-05-05
Android studio gradle環(huán)境變量配置教程
這篇文章主要為大家詳細(xì)介紹了Android studio gradle環(huán)境變量配置教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-05-05
Android實(shí)現(xiàn)可播放GIF動畫的ImageView
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)可播放GIF動畫的ImageView,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-09-09

