团队项目——第一阶段冲刺5
一、前言
1、昨天完成了:
优化验证码自动填充功能
2、今天完成了:
获取验证码倒计时效果
3、遇到的困难:
倒计时会出现漏掉数据的情况出现
二、设计思路
- 使用CountDownTimer倒计时器,点击按钮之后,按钮文字变为“ns后发送验证码”
- 为了让倒计时更加醒目,将秒数和单位设为蓝色
- 倒计时结束之后,按钮的文字显示为“重新发送”
三、逻辑代码
1.布局代码(先简单学习,后期进行整合优化)
<?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" android:padding="16dp" tools:context=".MainActivity"> <Button android:id="@+id/btn_captcha" android:layout_width="match_parent" android:layout_height="50dp" android:background="#c7c7c7" android:text="获取验证码" android:textAllCaps="false" android:textColor="@android:color/black" android:textSize="18sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
2.简单倒计时效果
public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Context context; private Button btnCaptcha; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); context = this; btnCaptcha = findViewById(R.id.btn_captcha); btnCaptcha.setOnClickListener(this); countTimer = new CountTimer(10000, 1000); } @Override public void onClick(View v) { countTimer.start(); } private CountTimer countTimer; /** * 点击按钮后倒计时 */ class CountTimer extends CountDownTimer { private SpannableStringBuilder sb; private ForegroundColorSpan colorSpan;
CountTimer(long millisInFuture, long countDownInterval) { super(millisInFuture, countDownInterval); sb = new SpannableStringBuilder(); colorSpan = new ForegroundColorSpan(ContextCompat.getColor(context, android.R.color.holo_blue_dark)); } /** * 倒计时过程中调用 * * @param millisUntilFinished */ @Override public void onTick(long millisUntilFinished) { Log.e("Tag", "millisUntilFinished=" + millisUntilFinished); // Log.e("Tag", "倒计时=" + (millisUntilFinished / 1000)); //处理后的倒计时数值 int time = (int) (Math.round((double) millisUntilFinished / 1000) - 1); //拼接要显示的字符串 sb.clear(); //先把之前的字符串清除 Log.e("Tag", "字符长度=" + sb.length()); sb.append(String.valueOf(time)); sb.append("s后重新发送"); int index = String.valueOf(sb).indexOf("后"); //给秒数和单位设置蓝色前景色 sb.setSpan(colorSpan, 0, index, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); btnCaptcha.setText(sb); //设置倒计时中的按钮外观 btnCaptcha.setClickable(false);//倒计时过程中将按钮设置为不可点击 btnCaptcha.setBackgroundColor(Color.parseColor("#c7c7c7")); btnCaptcha.setTextColor(ContextCompat.getColor(context, android.R.color.black)); btnCaptcha.setTextSize(16); } /** * 倒计时完成后调用 */ @Override public void onFinish() { Log.e("Tag", "倒计时完成"); //设置倒计时结束之后的按钮样式 btnCaptcha.setBackgroundColor(ContextCompat.getColor(context, android.R.color.holo_blue_light)); btnCaptcha.setTextColor(ContextCompat.getColor(context, android.R.color.white)); btnCaptcha.setTextSize(18); btnCaptcha.setText("重新发送"); btnCaptcha.setClickable(true); } } @Override protected void onDestroy() { super.onDestroy(); countTimer.cancel(); }
注意:
我采用的倒计时读数是将 millisUntilFinished 除于1000得到的,这里就产生了一个问题:millisUntilFinished 是长整型变量,除于1000之后得到是整数部分,由于程序运行需要花费时间,所以极有可能出现数据丢失的情况。
解决方法:
先将millisUntilFinished转换成double类型后再除于1000,这样就可以保留小数部分了,然后使用Math类中的round方法四舍五入。
修改后的onTick方法代码是这样的:
public void onTick(long millisUntilFinished) { //处理后的倒计时数值 int time = (int) (Math.round((double) millisUntilFinished / 1000) - 1); btnCaptcha.setText(String.valueOf(time)+"s后重新发送"); //设置倒计时中的按钮外观 btnCaptcha.setClickable(false);//倒计时过程中将按钮设置为不可点击 btnCaptcha.setBackgroundColor(Color.parseColor("#c7c7c7")); btnCaptcha.setTextColor(ContextCompat.getColor(context, android.R.color.black)); btnCaptcha.setTextSize(16); }
3.倒计时读数背景色
//处理后的倒计时数值 int time = (int) (Math.round((double) millisUntilFinished / 1000) - 1); //拼接要显示的字符串 sb.clear(); //先把之前的字符串清除 Log.e("Tag", "字符长度=" + sb.length()); sb.append(String.valueOf(time)); sb.append("s后重新发送"); int index = String.valueOf(sb).indexOf("后"); //给秒数和单位设置蓝色前景色 sb.setSpan(colorSpan, 0, index, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); btnCaptcha.setText(sb); //设置倒计时中的按钮外观 btnCaptcha.setClickable(false);//倒计时过程中将按钮设置为不可点击 btnCaptcha.setBackgroundColor(Color.parseColor("#c7c7c7")); btnCaptcha.setTextColor(ContextCompat.getColor(context, android.R.color.black)); btnCaptcha.setTextSize(16);
三、测试成果展示