我得到了一个片段,它有一个名为RingProgress
的控件,它只是一个根据给定的百分比值填充自身的环。例如,如果我这样做:
ringProgress.setProgress(20);
这意味着现在将填充20%的戒指。
我正在尝试做的是在几秒钟内为正在填充的戒指设置动画。所以我试图做的是:
@Override
public void onResume()
{
super.onResume();
HandlerThread handlerThread = new HandlerThread("countdown");
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper());
handler.post(new Runnable()
{
@Override
public void run()
{
final Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask()
{
int totalSeconds = secondsToStart + minutesToStart * 60;
int secondsPassed = 0;
@Override
public void run()
{
if(secondsPassed == totalSeconds)
{
timer.cancel();
}
final int currentProgress = (secondsPassed / totalSeconds) * 100;
secondsPassed++;
getActivity().runOnUiThread(new Runnable()
{
@Override
public void run()
{
mRingProgressBar.setProgress(currentProgress);
}
});
}
}, 0, 1000);
}
});
}
问题是直到时间到时才显示环的更新。例如,如果我将其设置为5秒,那么当片段加载时,环被设置为0,则5秒内没有任何事情发生,然后环完全100%全部一次...
如何正确启动此动画?
答案 0 :(得分:3)
我猜问题是
final int currentProgress = (secondsPassed / totalSeconds) * 100;
secondsPassed / totalSeconds
返回int值,因此它将仅为0或1。然后你将它乘以100。
您必须使用float
或double
代替
类似
final int currentProgress = Math.round(((float) secondsPassed)/((float) totalSeconds)*100f);
答案 1 :(得分:2)
在这一行:
Handler handler = new Handler(handlerThread.getLooper());
您正试图从handlerThread
获取looper。但是你是如何确定你的looper已经被初始化了?
来自getLooper()
此方法返回与此线程关联的Looper。如果此线程未启动或isAlive()因任何原因返回false,则此方法将返回null。如果此线程已经启动,则此方法将阻塞,直到looper已初始化为止。
onLooperPrepared()
是回调,您可以确定Looper
已初始化,因此您可以构建逻辑。
因此,您需要做的是继承HandlerThread
并从onLooperPrepared()
回调创建适当的逻辑。
Here's a nice post会帮助你。请参阅那里MyWorkerThread
类的实现。
答案 2 :(得分:1)
您可以使用属性动画器,而不是使用处理程序,如下所示:
ObjectAnimator.ofInt(mRingProgressBar, "progress", 0, 100)
.setDuration(totalSeconds * 1000) //time is in miliseconds
.start();
这将在setProgress()
中找到方法mRingProgressBar
,并根据给定的限制设置值。在上面的示例中,0到100。
您可以阅读更多相关信息here
答案 3 :(得分:0)
由于您希望在不同的线程上运行,因此您可以在该类的顶部使用此处理程序:
private int progress = 0;
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
@Override
public void run() {
ringProgress.setProgress(progress);
progress += 20;
if (progress == 100) { //clear??
}
timerHandler.postDelayed(this, 1000);
}
};
在inCreate
设置最大值:
ringProgress.setMax(100);
这将在5秒内完成动画,然后您可以清除动画。如果您想要更小的增量,请更改下面的行(每十分之一秒更新一次),然后更改步骤
timerHandler.postDelayed(this, 100);