Android 安卓视图没有';在尝试设置值时不随时间更新
我得到了一个片段,它得到了一个名为Android 安卓视图没有';在尝试设置值时不随时间更新,android,android-animation,android-runonuithread,Android,Android Animation,Android Runonuithread,我得到了一个片段,它得到了一个名为RingProgress的控件,它只是一个根据给定的百分比值填充自身的环。例如,如果我这样做: ringProgress.setProgress(20); timerHandler.postDelayed(this, 100); 这意味着20%的戒指将被填满 timerHandler.postDelayed(this, 100); 我想做的是,在几秒钟内给戒指加上动画。所以我试着做的是: @Override public void onResume() {
RingProgress
的控件,它只是一个根据给定的百分比值填充自身的环。例如,如果我这样做:
ringProgress.setProgress(20);
timerHandler.postDelayed(this, 100);
这意味着20%的戒指将被填满
timerHandler.postDelayed(this, 100);
我想做的是,在几秒钟内给戒指加上动画。所以我试着做的是:
@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);
}
});
}
timerHandler.postDelayed(this, 100);
问题是直到时间到了才显示环的更新。例如,如果我将其设置为5秒,那么当碎片加载时,环被设置为0,那么在5秒内什么都没有发生,然后环一次充满100%
timerHandler.postDelayed(this, 100);
如何正确启动此动画?我想问题在于
final int currentProgress = (secondsPassed / totalSeconds) * 100;
timerHandler.postDelayed(this, 100);
secondsPassed/totalSeconds
返回int值,使其仅为0或1。把它乘以100
timerHandler.postDelayed(this, 100);
您必须使用float
或double
timerHandler.postDelayed(this, 100);
差不多
final int currentProgress = Math.round(((float) secondsPassed)/((float) totalSeconds)*100f);
timerHandler.postDelayed(this, 100);
我想问题出在
final int currentProgress = (secondsPassed / totalSeconds) * 100;
timerHandler.postDelayed(this, 100);
secondsPassed/totalSeconds
返回int值,使其仅为0或1。把它乘以100
timerHandler.postDelayed(this, 100);
您必须使用float
或double
timerHandler.postDelayed(this, 100);
差不多
final int currentProgress = Math.round(((float) secondsPassed)/((float) totalSeconds)*100f);
timerHandler.postDelayed(this, 100);
您可以按如下方式使用属性动画制作程序,而不是使用处理程序:
ObjectAnimator.ofInt(mRingProgressBar, "progress", 0, 100)
.setDuration(totalSeconds * 1000) //time is in miliseconds
.start();
timerHandler.postDelayed(this, 100);
这将在mRingProgressBar
中找到方法setProgress()
,并根据给定的限制设置值。在上面的示例中,0到100。
您可以阅读更多有关它的信息,而不是使用处理程序,您可以使用属性动画制作程序,如下所示:
ObjectAnimator.ofInt(mRingProgressBar, "progress", 0, 100)
.setDuration(totalSeconds * 1000) //time is in miliseconds
.start();
timerHandler.postDelayed(this, 100);
这将在mRingProgressBar
中找到方法setProgress()
,并根据给定的限制设置值。在上面的示例中,0到100。
您可以在这一行阅读更多关于它的内容:
Handler handler = new Handler(handlerThread.getLooper());
timerHandler.postDelayed(this, 100);
您正试图从handlerThread
获取活套。但是你有多确定活套已经初始化了
timerHandler.postDelayed(this, 100);
从getLooper()的文档中
timerHandler.postDelayed(this, 100);
此方法返回与此线程关联的循环器。如果此线程未启动或由于任何原因为isAlive(),则返回false,此方法将返回null。如果此线程已启动,此方法将阻塞,直到循环器已初始化
timerHandler.postDelayed(this, 100);
onLooperPrepared()
是一个回调函数,您可以在其中确定循环器已初始化,因此可以在此基础上构造逻辑
timerHandler.postDelayed(this, 100);
因此,您必须做的是将HandlerThread
子类化,并从onLooperPrepared()
回调创建适当的逻辑
timerHandler.postDelayed(this, 100);
这会帮你的。请参见此处MyWorkerThread类的实现。在这一行:
Handler handler = new Handler(handlerThread.getLooper());
timerHandler.postDelayed(this, 100);
您正试图从handlerThread
获取活套。但是你有多确定活套已经初始化了
timerHandler.postDelayed(this, 100);
从getLooper()的文档中
timerHandler.postDelayed(this, 100);
此方法返回与此线程关联的循环器。如果此线程未启动或由于任何原因为isAlive(),则返回false,此方法将返回null。如果此线程已启动,此方法将阻塞,直到循环器已初始化
timerHandler.postDelayed(this, 100);
onLooperPrepared()
是一个回调函数,您可以在其中确定循环器已初始化,因此可以在此基础上构造逻辑
timerHandler.postDelayed(this, 100);
因此,您必须做的是将HandlerThread
子类化,并从onLooperPrepared()
回调创建适当的逻辑
timerHandler.postDelayed(this, 100);
这会帮你的。请参见此处的MyWorkerThread类的实现。因为您希望在不同的线程上运行,所以可以在类的顶部使用此处理程序:
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);
}
};
timerHandler.postDelayed(this, 100);
在inCreate
中设置最大值:
ringProgress.setMax(100);
timerHandler.postDelayed(this, 100);
这将在5秒内完成动画,然后可以清除动画。如果需要较小的增量,请更改下面的行(每十分之一秒更新一次),然后更改步骤
timerHandler.postDelayed(this, 100);
由于您希望在不同的线程上运行,因此可以在类的顶部使用此处理程序:
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);
}
};
timerHandler.postDelayed(this, 100);
在inCreate
中设置最大值:
ringProgress.setMax(100);
timerHandler.postDelayed(this, 100);
这将在5秒内完成动画,然后可以清除动画。如果需要较小的增量,请更改下面的行(每十分之一秒更新一次),然后更改步骤
timerHandler.postDelayed(this, 100);
您是否应用了日志记录/断点来查看是否调用了所有内容?ringProgress.setProgress(20)仅当您设置ringProgress.setMax(100)
时,code>将为20%;是否必须通过处理程序执行此操作?否不是必须的。。这只是我试图以不同的方式制作动画的东西thread@dumazy是否调用了所有内容应用了日志记录/断点以查看是否调用了所有内容?ringProgress.setProgress(20)仅当您设置ringProgress.setMax(100)
时,code>将为20%;是否必须通过处理程序执行此操作?否不是必须的。。这只是我试图以不同的方式制作动画的东西thread@dumazy是的,一切都被调用这将解释为什么只在末尾更新进度也可以执行secondsPassed*100/totalSeconds
,这将产生相同的结果,而不需要强制执行所有数字。此外,如果其中一个值是浮点值
,则不需要强制转换其他值,这意味着如果您已经有(float)secondsPassed
@Yonatan Nir,则不需要使用(float)totalSeconds
和100f
,尽管这似乎是确切的问题,但您的代码不可靠,因为处理程序的使用不正确。看我的答案。这确实是当前实施的问题。我只是竖起大拇指,没有接受,因为埃德森给我的答案让一切变得简单多了。这可以解释为什么进度只在末尾更新。也可以执行秒间隔*100/totalSeconds
,这将导致没有