Android中实现发送验证码功能,以及重新发送

Android中实现发送验证码功能,以及重新发送

  1. 引入splitedittext框架;
    //类似滴滴出行验证码输入框控件
    //https://github.com/jenly1314/SplitEditText
    implementation 'com.github.jenly1314:splitedittext:1.1.0'
  1. 页面中创建控件
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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=".component.input.activity.InputCodeActivity">

    <include layout="@layout/toolbar"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="@dimen/d30"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/verification_code"
            android:textColor="?attr/colorOnSurface"
            android:textSize="@dimen/text_large2"
            android:textStyle="bold"/>

        <TextView
            android:id="@+id/code_send_target"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/d10"
            android:text="@string/verification_code_sent_to"
            android:textColor="?attr/colorOnSurface"
            android:textSize="@dimen/s14"/>

<!--        验证码输入框-->
        <com.king.view.splitedittext.SplitEditText
            android:id="@+id/code"
            android:layout_width="match_parent"
            android:layout_height="@dimen/d50"
            android:layout_marginTop="@dimen/d40"
            android:inputType="number"
            app:setBorderColor="@color/divider"
            app:setBorderCornerRadius="@dimen/d5"
            app:setInputBorderColor="?attr/colorPrimary"/>

        <Button
            android:id="@+id/resend"
            style="?android:attr/borderlessButtonStyle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            android:textColor="@color/black80"
            android:text="@string/resend"/>

    </LinearLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>
  1. 代码中使用,调度;
package com.ixuea.courses.mymusic.component.input.activity;

import static autodispose2.AutoDispose.autoDisposable;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.View;

import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import com.ixuea.courses.mymusic.R;
import com.ixuea.courses.mymusic.component.api.HttpObserver;
import com.ixuea.courses.mymusic.component.input.activity.model.ui.InputCodePageData;
import com.ixuea.courses.mymusic.component.input.model.CodeRequest;
import com.ixuea.courses.mymusic.component.login.activity.BaseLoginActivity;
import com.ixuea.courses.mymusic.component.password.activity.SetPasswordActivity;
import com.ixuea.courses.mymusic.component.password.model.ui.SetPasswordPageData;
import com.ixuea.courses.mymusic.databinding.ActivityInputCodeBinding;
import com.ixuea.courses.mymusic.model.Base;
import com.ixuea.courses.mymusic.model.response.DetailResponse;
import com.ixuea.courses.mymusic.repository.DefaultRepository;
import com.ixuea.courses.mymusic.util.Constant;
import com.king.view.splitedittext.SplitEditText;

import org.apache.commons.lang3.StringUtils;

import autodispose2.androidx.lifecycle.AndroidLifecycleScopeProvider;

/**
 * 输入验证码界面
 * <p>
 * 可以是手机验证,也可以邮箱验证码
 */
public class InputCodeActivity extends BaseLoginActivity<ActivityInputCodeBinding> {

    private InputCodePageData pageData;
    private CodeRequest codeRequest;
    private int codeStyle;
    private CountDownTimer countDownTimer;

    @Override
    protected void initDatum() {
        super.initDatum();
        pageData = extraData();

        codeRequest = new CodeRequest();

        String target;
        if(StringUtils.isNotBlank(pageData.getPhone())){
            target = pageData.getPhone();
            codeStyle = Constant.VALUE10;
            codeRequest.setPhone(pageData.getPhone());
        }else{
            target=pageData.getEmail();
            codeStyle = Constant.VALUE0;
            codeRequest.setEmail(pageData.getEmail());
        }

        binding.codeSendTarget.setText(getString(R.string.verification_code_sent_to,target));

        sendCode();
    }

    private void sendCode() {
        DefaultRepository.getInstance()
                .sendCode(codeStyle, codeRequest)
                .to(autoDisposable(AndroidLifecycleScopeProvider.from(this)))
                .subscribe(new HttpObserver<DetailResponse<Base>>() {
                    @Override
                    public void onSucceeded(DetailResponse<Base> data) {
                        //发送成功了

                        //开始倒计时
                        startCountDown();
                    }
                });
    }

    /**
     * 开始倒计时
     * 现在没有保存退出的状态
     * 也就说,返回在进来就可以点击了
     */
    private void startCountDown() {
        //倒计时的总时间,间隔
        //单位是毫秒
        countDownTimer = new CountDownTimer(60000,1000) {
            /**
             * 间隔时间调用
             * @param millisUntilFinished The amount of time until finished.
             */
            @Override
            public void onTick(long millisUntilFinished) {
                binding.resend.setText(getString(R.string.resend_count, millisUntilFinished / 1000));
            }

            /**
             * 倒计时完成
             */
            @Override
            public void onFinish() {
                binding.resend.setText(R.string.resend);

                binding.resend.setEnabled(true);
            }
        };

        //启动
        countDownTimer.start();

        binding.resend.setEnabled(false);
    }

    @Override
    protected void initListeners() {
        super.initListeners();

        binding.code.setOnTextInputListener(new SplitEditText.OnSimpleTextInputListener() {
            @Override
            public void onTextInputCompleted(@NonNull String s) {
                processNext(s);
            }
        });

        binding.resend.setOnClickListener(v -> sendCode());
    }

    private void processNext(String data){
        if(pageData.getStyle() == Constant.STYLE_PHONE_LOGIN){
            //手机号验证码登录
            login(pageData.getPhone(),data);
        }else{
            //先校验验证码
            codeRequest.setCode(data);
            DefaultRepository.getInstance()
                    .checkCode(codeRequest)
                    .to(autoDisposable(AndroidLifecycleScopeProvider.from(this)))
                    .subscribe(new HttpObserver<DetailResponse<Base>>() {
                        @Override
                        public void onSucceeded(DetailResponse<Base> d) {
                            //重设密码
                            SetPasswordActivity.start(getHostActivity(), new SetPasswordPageData(
                                    pageData.getPhone(),
                                    pageData.getEmail(),
                                    data
                            ));
                        }

                        @Override
                        public boolean onFailed(DetailResponse<Base> data, Throwable e) {
                            //清除验证码输入的内容
                            binding.code.setText("");
                            return super.onFailed(data, e);
                        }
                    });
        }
    }

    @Override
    protected void onDestroy() {
        //销毁定时器
        if(countDownTimer !=null){
            countDownTimer.cancel();
            countDownTimer = null;
        }
        super.onDestroy();
    }

    public static void start(Context context, InputCodePageData data) {
        Intent intent = new Intent(context, InputCodeActivity.class);
        intent.putExtra(Constant.DATA, data);
        context.startActivity(intent);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值