如何从postdelay添加的处理程序对象中删除runnable ?

时间:2021-03-12 17:32:15

I have an "open" animation and am using Handler.postDelayed(Runnable, delay) to trigger a "close" animation after a short delay. However, during the time between open and close, there is possibly another animation triggered by a click.

我有一个“打开”动画并且正在使用处理器。延迟(Runnable, delay)在短暂延迟后触发“关闭”动画。然而,在打开和关闭之间,可能会有另一个由单击触发的动画。

My question is, how would I cancel the "close" animation in the handler?

我的问题是,如何取消处理程序中的“close”动画?

4 个解决方案

#1


87  

Just use the removeCallbacks(Runnable r) method.

只需使用removeCallbacks(Runnable r)方法。

#2


83  

Cristian's answer is correct, but as opposed to what is stated in the answer's comments, you actually can remove callbacks for anonymous Runnables by calling removeCallbacksAndMessages(null);

克里斯蒂安的答案是正确的,但是与答案注释中所陈述的相反,您实际上可以通过调用removeCallbacksAndMessages(null)来删除匿名Runnables的回调;

As stated here:

这里是这样陈述的:

Remove any pending posts of callbacks and sent messages whose obj is token. If token is null, all callbacks and messages will be removed.

删除回调的任何挂起的帖子,并发送其obj为令牌的消息。如果令牌为空,则将删除所有回调和消息。

#3


11  

This is a late answer, but here's a different method for when you only want to remove a specific category of runnables from the handler (i.e. in OP's case, just remove the close animation, leaving other runnables in the queue):

这是一个较晚的答案,但这里有一个不同的方法,当您只需要从处理程序中移除特定的runnables类别时(例如,在OP的情况下,只需删除关闭动画,将其他runnables留在队列中):

    int firstToken = 5;
    int secondToken = 6;

    //r1 to r4 are all different instances or implementations of Runnable.  
    mHandler.postAtTime(r1, firstToken, 0);
    mHandler.postAtTime(r2, firstToken, 0);
    mHandler.postAtTime(r3, secondToken, 0);

    mHandler.removeCallbacksAndMessages(firstToken);

    mHandler.postAtTime(r4, firstToken, 0);

The above code will execute "r3" and then "r4" only. This lets you remove a specific category of runnables defined by your token, without needing to hold any references to the runnables themselves.

上面的代码将只执行“r3”,然后只执行“r4”。这允许您删除标记定义的特定类型的runnables,而不需要对runnables本身进行任何引用。

Note: the source code compares tokens using the "==" operand only (it does not call .equals()), so best to use ints/Integers instead of strings for the token.

注意:源代码只使用“==”操作数比较令牌(它不调用.equals())),所以最好使用int / integer而不是string作为令牌。

#4


8  

If your using recursion, you can acheive this by passing "this". See code below.

如果您使用递归,您可以通过传递“this”来消除这个错误。请参见下面的代码。

public void countDown(final int c){
    mHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
            aq.id(R.id.timer).text((c-1)+"");
            if(c <= 1){
                aq.id(R.id.timer).gone();
                mHandler.removeCallbacks(this);
            }else{
                countDown(c-1);
            }
        }
    }, 1000);
}

This example will set the text of a TextView (timer) every second, counting down. Once it gets to 0, it will remove the the TextView from the UI and disable the countdown. This is only useful for someone who is using recursion, but I arrived here searching for that, so I'm posting my results.

这个示例将每秒设置TextView (timer)的文本,计数。一旦它达到0,它将从UI中删除TextView并禁用倒计时。这只对使用递归的人有用,但我在这里搜索,所以我发布了我的结果。

#1


87  

Just use the removeCallbacks(Runnable r) method.

只需使用removeCallbacks(Runnable r)方法。

#2


83  

Cristian's answer is correct, but as opposed to what is stated in the answer's comments, you actually can remove callbacks for anonymous Runnables by calling removeCallbacksAndMessages(null);

克里斯蒂安的答案是正确的,但是与答案注释中所陈述的相反,您实际上可以通过调用removeCallbacksAndMessages(null)来删除匿名Runnables的回调;

As stated here:

这里是这样陈述的:

Remove any pending posts of callbacks and sent messages whose obj is token. If token is null, all callbacks and messages will be removed.

删除回调的任何挂起的帖子,并发送其obj为令牌的消息。如果令牌为空,则将删除所有回调和消息。

#3


11  

This is a late answer, but here's a different method for when you only want to remove a specific category of runnables from the handler (i.e. in OP's case, just remove the close animation, leaving other runnables in the queue):

这是一个较晚的答案,但这里有一个不同的方法,当您只需要从处理程序中移除特定的runnables类别时(例如,在OP的情况下,只需删除关闭动画,将其他runnables留在队列中):

    int firstToken = 5;
    int secondToken = 6;

    //r1 to r4 are all different instances or implementations of Runnable.  
    mHandler.postAtTime(r1, firstToken, 0);
    mHandler.postAtTime(r2, firstToken, 0);
    mHandler.postAtTime(r3, secondToken, 0);

    mHandler.removeCallbacksAndMessages(firstToken);

    mHandler.postAtTime(r4, firstToken, 0);

The above code will execute "r3" and then "r4" only. This lets you remove a specific category of runnables defined by your token, without needing to hold any references to the runnables themselves.

上面的代码将只执行“r3”,然后只执行“r4”。这允许您删除标记定义的特定类型的runnables,而不需要对runnables本身进行任何引用。

Note: the source code compares tokens using the "==" operand only (it does not call .equals()), so best to use ints/Integers instead of strings for the token.

注意:源代码只使用“==”操作数比较令牌(它不调用.equals())),所以最好使用int / integer而不是string作为令牌。

#4


8  

If your using recursion, you can acheive this by passing "this". See code below.

如果您使用递归,您可以通过传递“this”来消除这个错误。请参见下面的代码。

public void countDown(final int c){
    mHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
            aq.id(R.id.timer).text((c-1)+"");
            if(c <= 1){
                aq.id(R.id.timer).gone();
                mHandler.removeCallbacks(this);
            }else{
                countDown(c-1);
            }
        }
    }, 1000);
}

This example will set the text of a TextView (timer) every second, counting down. Once it gets to 0, it will remove the the TextView from the UI and disable the countdown. This is only useful for someone who is using recursion, but I arrived here searching for that, so I'm posting my results.

这个示例将每秒设置TextView (timer)的文本,计数。一旦它达到0,它将从UI中删除TextView并禁用倒计时。这只对使用递归的人有用,但我在这里搜索,所以我发布了我的结果。