Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”
This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.
preface
In actual projects, we often meet the requirement of countdown, for example, we need to limit the user's access to verification code when logging in, and limit the binding of mailbox or third-party account to prevent unnecessary losses to the company.
Realize there are many ways of, such as a Handler, CountDownTimer, Timer, although the countdown sounds simple, but involves a lot of logic, I listed first
- The data decreases slowly over time, and the text changes when it reaches 0
To resend
Or other copywriting - When the user clicks, the countdown begins, the font color changes to gray, and it is not clickable
- When the time countdown ends, the font color changes to normal color, and can be clicked.
- Global record countdown time, to prevent stupid users from messing around (although the server can operate, we also need to consider this situation on the client side)
Code
At first, I thought I would use SharedPrefences to save the prefences locally, but this logic was cumbersome, and although we encapsulated it, the logic could not be too long, so we switched to the singleton mode
public class TimeCount {
public static TimeCount getInstance() {
if (timeCount == null) {
synchronized (TimeCount.class) {
if (timeCount == null) {
timeCount = new TimeCount();
}
}
}
return timeCount;
}
}
Copy the code
Then we need to bind our control to this singleton class
@SuppressLint("StaticFieldLeak") private static volatile TimeCount timeCount = null; // page private Activity mActivity; // control private TextView messageEmailText; /** * @param activity * @param textView * @return binding control */ public TimeCount bindTextView(activity activity, TextView textView) { mActivity = activity; messageEmailText = textView; return this; }Copy the code
This time we chose to use CountDownTimer for encapsulation. Let’s define the logic of the countdown first
public class Count extends CountDownTimer { public Count(long millisInFuture, long countDownInterval) { super(millisInFuture, countDownInterval); } @SuppressLint("SetTextI18n") @Override public void onTick(long millisUntilFinished) { if (messageEmailText ! = null && messageEmailText.getVisibility() == View.VISIBLE && mActivity ! = null && ! mActivity.isFinishing()) { messageEmailText.setEnabled(false); Messageemailtext.settext ("(" + ^ ^ ^ ^ ^ ^) "); messageemailtext.settext ("(" + ^ ^ ^ ^ ^) "); } } @Override public void onFinish() { if (messageEmailText ! = null && messageEmailText.getVisibility() == View.VISIBLE && mActivity ! = null && ! Mactive.isfinishing ()) {messageEmailText.settext (" resend "); messageEmailText.setEnabled(true); } emailCount = null; cancel(); }}Copy the code
I’m not going to explain CountDownTimer, you can go to Baidu if you need it, but for every step that you set, it’s going to call onTick, and when it’s done it’s going to call onFinish.
- constructional
super
The first parameter is the total time in milliseconds; The second parameter is the step of time. messageEmailText
Is in thebindTextView
TextView, which checks whether it is visible or not.mActivity
It is also ourbindTextview
The argument passed, which checks if it is not null, is closed. To prevent some low-level exception errors.onTick
In thesetEnabled
TextView must be unclickable in the countdown.onTick
Parameter for the callback inmillisUntilFinished
It’s the remaining time, which is just milliseconds, so we’re going to do it very simply.onFinish
There is no explanation for the truth,cancel
Cancel the countdown,setEnabled
So I can click,emailCount = null;
We’ll talk about that later why
After the countdown logic and classes are handled, let’s write a method to start
Timing starts / * * * * * @ param millisInFuture * / public void startCountTimer (long millisInFuture) {/ / the countdown, if use the singleton storage time (emailCount == null) { emailCount = new Count(millisInFuture, 1000); } // start the countdown emailcount.start (); if (messageEmailText ! = null) { messageEmailText.setEnabled(true); messageEmailText.setTextColor(ContextCompat.getColor(mActivity, R.color.gray)); }}Copy the code
EmailCount = null; It echoes.
Okay, let’s use it
TimeCount.getInstance().bindTextView(this,mTv)
.startCountTimer(10000);
Copy the code