验证码输入框倒计时

在我们的应用中,有些地方需要我们输入验证码的操作,并且带有倒计时功能,比如说忘记密码,修改手机号码,激活等等,整好我的项目中也用到了,就贴出来供大家参考。

实现原理很简单就是在布局中同时添加TextView和Editext,并且他们是重叠在一起的,我么通过Editext的监听来将获取到的内容放到Text里面。

倒计时功能: 自定义控件继承CountDownTimer类,实现它的onTick和onFinish方法,具体讲解在代码中。



                        

package jx.com.verificationcode;

import android.content.Context;
import android.os.CountDownTimer;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ForegroundColorSpan;
import android.widget.TextView;

/**
 * Created by zsd on 2016/6/27.
 * 倒计时
 */

public class CountDownTimerUtils extends CountDownTimer {

    private TextView mTextView;
    private Context mContext;

    public CountDownTimerUtils(TextView textView, long millisInFuture, long countDownInterval) {
        super(millisInFuture, countDownInterval);
        this.mTextView = textView;
    }

    @Override
    public void onTick(long millisUntilFinished) {
        mTextView.setClickable(false); //设置不可点击
        mTextView.setText("重新获取验证码" + millisUntilFinished / 1000 + "s");  //设置倒计时时间
        mTextView.setTextSize(14);
//        mTextView.setBackgroundResource(R.drawable.bg_identify_code_press); //设置按钮为灰色,这时是不能点击的

        /**
         * 超链接 URLSpan
         * 文字背景颜色 BackgroundColorSpan
         * 文字颜色 ForegroundColorSpan
         * 字体大小 AbsoluteSizeSpan
         * 粗体、斜体 StyleSpan
         * 删除线 StrikethroughSpan
         * 下划线 UnderlineSpan
         * 图片 ImageSpan
         * http://blog.youkuaiyun.com/ah200614435/article/details/7914459
         */
        SpannableString spannableString = new SpannableString(mTextView.getText().toString());  //获取按钮上的文字
        ForegroundColorSpan span = new ForegroundColorSpan(BaseApplication.getAppContext().getResources().getColor(R.color.colorBlue));
        /**
         * public void setSpan(Object what, int start, int end, int flags) {
         * 主要是start跟end,start是起始位置,无论中英文,都算一个。
         * 从0开始计算起。end是结束位置,所以处理的文字,包含开始位置,但不包含结束位置。
         */
        spannableString.setSpan(span, 7, mTextView.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);//将倒计时的时间设置为蓝色
        mTextView.setText(spannableString);
    }

    @Override
    public void onFinish() {
        mTextView.setText("重新获取验证码");
        mTextView.setClickable(true);//重新获得点击
//        mTextView.setBackgroundResource(R.drawable.bg_identify_code_normal);  //还原背景色
    }
}


简易实现逻辑:

        输入手机号码或者邮箱,从后台获取验证码,手机号码输入及邮箱输入就不写了,跳转到到验证页面,,然后将手机或邮箱的验证码填入到验证码输入框进行验证

验证码CheckCodeView实现代码

package jx.com.verificationcode;

import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;

/**
 * Created by zsd on 16/6/27.
 */

public class CheckCodeView extends RelativeLayout {


    private EditText editText;
    private TextView[] TextViews; //用于存放输入的数字
    private StringBuffer stringBuffer = new StringBuffer();
    private int count = 4; //输入的个数,这个可以自己根据需求来定义
    private String inputContent; //输入内容

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

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

    public CheckCodeView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TextViews = new TextView[4];
        View.inflate(context, R.layout.view_check_code, this);

        editText = (EditText) findViewById(R.id.item_edittext);
        TextViews[0] = (TextView) findViewById(R.id.item_code_iv1);
        TextViews[1] = (TextView) findViewById(R.id.item_code_iv2);
        TextViews[2] = (TextView) findViewById(R.id.item_code_iv3);
        TextViews[3] = (TextView) findViewById(R.id.item_code_iv4);

        editText.setCursorVisible(false);//将光标隐藏
        //editext的监听
        editText.addTextChangedListener(mEditextWatchListener);
        editText.setOnKeyListener(mOnkeyListener);
    }

    TextWatcher mEditextWatchListener = 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.toString().equals("")) {
                if (stringBuffer.length() > 3) {
                    //当文本长度大于3位时edittext置空
                    editText.setText("");
                    return;
                } else {
                    //将文字添加到StringBuffer中
                    stringBuffer.append(editable);
                    editText.setText("");//添加后将EditText置空
                    //  Log.e("TAG", "afterTextChanged: stringBuffer is " + stringBuffer);
                    count = stringBuffer.length();//记录stringbuffer的长度
                    inputContent = stringBuffer.toString();
                    if (stringBuffer.length() == 4) {
                        //文字长度位4  则调用完成输入的监听
                        if (inputCompleteListener != null) {
                            inputCompleteListener.inputComplete();
                        }
                    }
                }

                for (int i = 0; i < stringBuffer.length(); i++) {
                    TextViews[i].setText(String.valueOf(inputContent.charAt(i)));
                    TextViews[i].setBackgroundResource(R.mipmap.bg_verify_press);
                }

            }
        }
    };

    OnKeyListener mOnkeyListener = new OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_DEL&& event.getAction() == KeyEvent.ACTION_DOWN) {
                if (onKeyDelete()) return true;
                return true;
            }
            return false;
        }
    };


    public boolean onKeyDelete() {
        if (count == 0) {
            count = 4;
            return true;
        }
        if (stringBuffer.length() > 0) {
            //删除相应位置的字符
            stringBuffer.delete((count - 1), count);
            count--;
            inputContent = stringBuffer.toString();
            TextViews[stringBuffer.length()].setText("");
            TextViews[stringBuffer.length()].setBackgroundResource(R.mipmap.bg_verify);
            if (inputCompleteListener != null)
                inputCompleteListener.deleteContent(true);//有删除就通知manger

        }
        return false;
    }

    /**
     * 清空输入内容
     */
    public void clearEditText() {
        stringBuffer.delete(0, stringBuffer.length());
        inputContent = stringBuffer.toString();
        for (int i = 0; i < TextViews.length; i++) {
            TextViews[i].setText("");
            TextViews[i].setBackgroundResource(R.mipmap.bg_verify);
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        return super.onKeyDown(keyCode, event);
    }

    private InputCompleteListener inputCompleteListener;

    public void setInputCompleteListener(InputCompleteListener inputCompleteListener) {
        this.inputCompleteListener = inputCompleteListener;
    }

    public interface InputCompleteListener {
        void inputComplete();

        void deleteContent(boolean isDelete);
    }

    /**
     * 获取输入文本
     *
     * @return
     */
    public String getEditContent() {
        return inputContent;
    }

}

view_check_code.xml布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="47dp"
        android:gravity="center"
        android:orientation="horizontal"
        android:weightSum="3">


        <TextView
            android:id="@+id/item_code_iv1"
            style="@style/edit_style" />

        <View
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <TextView
            android:id="@+id/item_code_iv2"
            style="@style/edit_style" />

        <View
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <TextView
            android:id="@+id/item_code_iv3"
            style="@style/edit_style" />

        <View
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <TextView
            android:id="@+id/item_code_iv4"
            style="@style/edit_style" />


    </LinearLayout>

    <EditText
        android:id="@+id/item_edittext"
        android:layout_width="match_parent"
        android:layout_height="46dp"
        android:background="@android:color/transparent"
        android:inputType="number" />
</RelativeLayout>

edit_style:

     

    <style name="edit_style" >
        <item name="android:layout_height">47dp</item>
        <item name="android:layout_width">47dp</item>
        <item name="android:background">@mipmap/bg_verify</item>
        <item name="android:gravity">center</item>
        <item name="android:textColor">@color/common_blue_0090FF</item>
        <item name="android:textSize">18sp</item>
    </style>
验证码验证页面,需要验证验证码正确与否可以自行添加逻辑:

package jx.com.verificationcode;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import android.widget.Toast;

/**
 * Created by zsd on 2016/6/27
 * desc:
 */
public class SecondActivity extends AppCompatActivity implements CheckCodeView.InputCompleteListener {

    private CheckCodeView checkCodeView;
    private TextView text;
    private CountDownTimerUtils mCountDownTimerUtils;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        initView();
        checkCodeView.setInputCompleteListener(this);
        mCountDownTimerUtils = new CountDownTimerUtils(text, 60000, 1000);
        mCountDownTimerUtils.start();
    }

    private void initView() {
        checkCodeView = (CheckCodeView) findViewById(R.id.check_code_view);
        text = (TextView) findViewById(R.id.tv_text);
    }

    @Override
    public void inputComplete() {
        Toast.makeText(getApplicationContext(), "验证码是:" + checkCodeView.getEditContent(), Toast.LENGTH_LONG).show();
    }

    @Override
    public void deleteContent(boolean isDelete) {
        if (isDelete){
            text.setText("重新获取验证码");
            mCountDownTimerUtils.start();
        }
    }
}
activity_second.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <jx.com.verificationcode.CheckCodeView
        android:id="@+id/check_code_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginLeft="30dp"
        android:layout_marginRight="30dp"
        android:layout_marginTop="20dp" />

    <TextView
        android:id="@+id/tv_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/check_code_view"
        android:layout_centerInParent="true"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="40dp"
        android:textSize="16dp"
        android:text="重新获取验证码" />

</RelativeLayout>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值