In my application I have TabLayout with two tabs: Stopwatch and Timer. When I switch between this two tabs and timer is not running then everything works great. Problem occurs when I start timer, indicator animation is delayed. Below video demonstrating this issue:
https://media.giphy.com/media/xjLnjaQ0NgH0a4yqsO/giphy.gif
I think this is caused by short countDownInterwal in CountDownTimer. I set this to 50. This value is low because I want to have smooth time indicator (in my app blue big circle - Timer).
private void startTimer() {
countDownTimer = new CountDownTimer(timeLeftInMillis, 50) {
@Override
public void onTick(long millisUntilFinished) {
timeLeftInMillis = millisUntilFinished;
updateCountDownText();
mProgressBar1.setProgress((int) (timeLeftInMillis/10));
}
@Override
public void onFinish() {
finishCountDownTimer();
countDownSound.start();
showDialogWhenFinishCountDown();
}
}.start();
}
What sould I do to fix this problem?
A CountDownTimer
is not an optimal solution (for a start the entire class is synchronised
which causes immediate overhead), you shouldn't be animating this manually if you want smooth animations. Use what the Android Framework has to offer.
I used ObjectAnimator
with a very quick example :
Basic Fragment class - what you'll be most interested in is the startStopTimer()
method :
public class TimerFragment extends Fragment {
public TimerFragment() { }
private static int ONE_MINUTE_MILLIS = (int) TimeUnit.MINUTES.toMillis(1);
private ProgressBar progressBar;
private ObjectAnimator animator;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_timer, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
progressBar = view.findViewById(R.id.progressBar);
progressBar.setMax(ONE_MINUTE_MILLIS);
progressBar.setProgress(ONE_MINUTE_MILLIS);
view.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startStopTimer();
}
});
}
private void startStopTimer() {
if(animator == null) {
animator = ObjectAnimator.ofInt(progressBar, "progress", ONE_MINUTE_MILLIS, 0);
animator.setDuration(ONE_MINUTE_MILLIS);
animator.setInterpolator(new LinearInterpolator());
animator.start();
} else {
animator.cancel();
animator = null;
progressBar.setProgress(ONE_MINUTE_MILLIS);
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
if(animator != null) {
animator.cancel();
animator = null;
}
}
}