android studio模拟倒计时发送随机验证码功能

 在许多应用中,常常会实现发送验证码并倒计时的功能,以防止用户频繁请求验证码。本文将通过一个简单的示例展示如何在Android中模拟这项功能。

一、页面布局展示及代码

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".PasswordActivity">

    <ImageView
        android:id="@+id/imageView47"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/diand" />

    <TextView
        android:id="@+id/textView38"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="48dp"
        android:layout_marginTop="20dp"
        android:text="输入验证码"
        android:textSize="24sp"
        android:textStyle="bold"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/imageView47" />

    <EditText
        android:id="@+id/editTextPhone3"
        android:layout_width="290dp"
        android:layout_height="55dp"
        android:layout_marginTop="24dp"
        android:backgroundTint="#DCDCDC"
        android:ems="10"
        android:hint="验证码"
        android:inputType="phone"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="@+id/textView38"
        app:layout_constraintTop_toBottomOf="@+id/textView38" />

    <androidx.cardview.widget.CardView
        android:id="@+id/CardView"
        android:layout_width="300dp"
        android:layout_height="40dp"
        android:layout_marginTop="50dp"
        app:cardBackgroundColor="#2196F3"
        app:cardCornerRadius="20dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView94">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <TextView
                android:id="@+id/textView46"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="下一步"
                android:textColor="@color/white"
                android:textSize="24sp"
                android:textStyle="bold"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />
        </androidx.constraintlayout.widget.ConstraintLayout>
    </androidx.cardview.widget.CardView>

    <TextView
        android:id="@+id/textView94"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:text="TextView"
        android:textColor="#FF9800"
        android:textSize="20sp"
        app:layout_constraintStart_toStartOf="@+id/editTextPhone3"
        app:layout_constraintTop_toBottomOf="@+id/editTextPhone3" />

</androidx.constraintlayout.widget.ConstraintLayout>

二、倒计时并生成随机数功能

CountDownTimer是Android中的一个类,用于处理倒计时相关的逻辑。它可以在后台线程中进行倒计时操作,并且在计时结束时触发回调方法,允许你在UI上更新相应的显示。

通常情况下,你需要继承CountDownTimer类,并实现它的两个主要方法:onTick(long millisUntilFinished)和onFinish()。在onTick方法中,你可以处理每次计时间隔时需要执行的操作,比如更新UI上的倒计时显示;而onFinish方法则用于处理倒计时结束时需要执行的操作,比如更新UI状态或者触发相应的事件。

这里我实现的CountTimer类是一个自定义的倒计时器,继承自CountDownTimer类:

public class CountTimer extends CountDownTimer {
    private TextView mTextView;//存储倒计时提示
    public String verification; // 存储生成的验证码

    public CountTimer(TextView textView, long millisInFuture, long countDownInterval) {
        super(millisInFuture, countDownInterval);
        this.mTextView = textView;
        this.verification = generateRandomCode(6); // 生成6位随机验证码
    }

在onTick方法中,当倒计时进行中,TextView设置为不可点击状态,显示剩余时间的文本,同时使用SpannableString给文本添加灰色前景色,从而实现倒计时过程中的UI效果。

@Override
public void onTick(long millisUntilFinished) {
    mTextView.setClickable(false);
    mTextView.setText(millisUntilFinished / 1000 + "秒后重新发送");
    SpannableString spannableString = new SpannableString(mTextView.getText().toString());
    ForegroundColorSpan span = new ForegroundColorSpan(Color.GRAY);
    spannableString.setSpan(span, 0, spannableString.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
    mTextView.setText(spannableString);
}

在onFinish方法中,当倒计时结束时,将TextView的文本设置为"重新获取验证码",并将其设置为可点击状态,以便用户可以重新触发获取验证码的操作。

@Override
public void onFinish() {
    mTextView.setText("重新获取验证码");
    mTextView.setClickable(true);//重新获得点击
}

generateRandomCode方法用于生成指定长度的随机验证码,它通过Random类生成随机数,并将其转换为字符串返回。

private String generateRandomCode(int length) {
    Random random = new Random();
    StringBuilder code = new StringBuilder();
    for (int i = 0; i < length; i++) {
        code.append(random.nextInt(10));
    }
    return code.toString();
}

三、界面交互逻辑

在Activity中,通过调用以上的CountTimer类即可在界面显示倒计时并且提示用户对应的验证码。主要通过三句代码实现,其他的逻辑功能可自行添加,这里还利用了在倒计时的第3秒实现验证码弹窗。完整代码如下:

public class VerifyActivity extends AppCompatActivity {
    private CountTimer countTimer;
    private TextView textView94;
    private TextView textView42;
    private EditText editTextPhone3; // 用户输入验证码的输入框

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_verify);

        textView94 = findViewById(R.id.textView94);

        // 初始化倒计时
        initializeCountdown();

        // 设置点击事件监听器
        textView94.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 点击时重新启动倒计时
                initializeCountdown();
            }
        });

       /* textView42 = findViewById(R.id.textView42);
        String text="验证码已发送至"+phone;
        textView42.setText(text);
*/
        // 设置点击事件监听器->返回
        ImageView imageView = findViewById(R.id.imageView47);
        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //返回上一个页面
                finish();
            }
        });

        editTextPhone3 = findViewById(R.id.editTextPhone3);
        CardView cardView = findViewById(R.id.CardView);
        // 设置点击事件监听器
        cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String input = editTextPhone3.getText().toString(); // 获取用户输入的验证码
                if (countTimer != null && countTimer.getVerification().equals(input)) {
                    Intent intent = new Intent(VerifyActivity.this, PasswordActivity.class);
                    startActivity(intent);
                } else {

                    Toast.makeText(VerifyActivity.this, "验证码错误,请重新获取", Toast.LENGTH_SHORT).show();
                    editTextPhone3.setText(""); // 清空输入框

                }
            }
        });

    }

    private void initializeCountdown() {
        countTimer = new CountTimer(textView94, 5 * 1000, 1000);
        countTimer.start();

        // 使用Handler在3秒后显示弹窗
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                showVerificationDialog(countTimer.verification);
            }
        }, 3000); // 3000毫秒后执行
    }

    private void showVerificationDialog(String code) {
        AlertDialog.Builder builder = new AlertDialog.Builder(VerifyActivity.this);
        builder.setTitle("验证码通知");

        // 使用SpannableString来使验证码加粗
        SpannableString spannableString = new SpannableString("您好,欢迎注册,你的验证码是: " + code);
        spannableString.setSpan(new StyleSpan(Typeface.BOLD),
                spannableString.length() - code.length(),
                spannableString.length(),
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        builder.setMessage(spannableString);
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });

        AlertDialog dialog = builder.create();
        dialog.show();
    }

}

四、效果展示

五、总结

通过上述代码,就实现了一个简单的验证码倒计时功能。用户在点击获取验证码后,会启动倒计时,并在3秒后弹出包含验证码的对话框。同时,用户可以输入验证码进行验证。

希望这篇文章能对你有所帮助。如果你有任何问题或建议,欢迎在评论区留言。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值