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
,这将导致没有