72

我有一个“打开”动画,并在短暂延迟后Handler.postDelayed(Runnable, delay)用来触发“关闭”动画。但是,在打开和关闭之间的时间里,可能还有另一个由点击触发的动画。

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

4

4 回答 4

102

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

于 2010-09-02T13:10:52.863 回答
99

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

如此处所述:

删除所有待处理的回调和发送的消息,其 obj 是令牌。如果 token 为 null,所有回调和消息都将被删除

于 2013-02-10T15:40:16.610 回答
17

这是一个较晚的答案,但是当您只想从处理程序中删除特定类别的可运行文件时,这是一种不同的方法(即在 OP 的情况下,只需删除关闭动画,将其他可运行文件留在队列中):

    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);

上面的代码将只执行“r3”,然后执行“r4”。这使您可以删除由令牌定义的特定类别的可运行文件,而无需保存对可运行文件本身的任何引用。

注意:源代码仅使用“==”操作数比较标记(它不调用 .equals()),因此最好使用整数/整数而不是字符串作为标记。

于 2015-06-18T01:58:05.733 回答
11

如果您使用递归,则可以通过传递“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);
}

这个例子将每秒设置一个TextView(定时器)的文本,倒计时。一旦它变为 0,它将从 UI 中删除 TextView 并禁用倒计时。这仅对使用递归的人有用,但我到这里是为了寻找它,所以我发布了我的结果。

于 2012-01-24T02:45:23.187 回答