TabLayout - 指示器动画延迟
TabLayout - indicator animation is delayed
在我的应用程序中,我有带有两个选项卡的 TabLayout:秒表和计时器。当我在这两个选项卡之间切换并且计时器不是 运行 时,一切都很好。当我启动计时器时出现问题,指示器动画延迟。下面的视频展示了这个问题:
https://media.giphy.com/media/xjLnjaQ0NgH0a4yqsO/giphy.gif
我认为这是由于 CountDownTimer 中的 countDownInterwal 过短造成的。我将它设置为 50。这个值很低,因为我想要平滑的时间指示器(在我的应用程序中蓝色大圆圈 - 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();
}
我应该怎么做才能解决这个问题?
A CountDownTimer
不是最佳解决方案(一开始,整个 class 是 synchronised
,这会导致直接的开销),如果你愿意,你不应该手动设置动画流畅的动画。使用 Android 框架必须提供的功能。
我用 ObjectAnimator
举了一个非常简单的例子:
基本片段 class - 您最感兴趣的是 startStopTimer()
方法:
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;
}
}
}
在我的应用程序中,我有带有两个选项卡的 TabLayout:秒表和计时器。当我在这两个选项卡之间切换并且计时器不是 运行 时,一切都很好。当我启动计时器时出现问题,指示器动画延迟。下面的视频展示了这个问题:
https://media.giphy.com/media/xjLnjaQ0NgH0a4yqsO/giphy.gif
我认为这是由于 CountDownTimer 中的 countDownInterwal 过短造成的。我将它设置为 50。这个值很低,因为我想要平滑的时间指示器(在我的应用程序中蓝色大圆圈 - 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();
}
我应该怎么做才能解决这个问题?
A CountDownTimer
不是最佳解决方案(一开始,整个 class 是 synchronised
,这会导致直接的开销),如果你愿意,你不应该手动设置动画流畅的动画。使用 Android 框架必须提供的功能。
我用 ObjectAnimator
举了一个非常简单的例子:
基本片段 class - 您最感兴趣的是 startStopTimer()
方法:
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;
}
}
}