我有一个“打开”动画,并使用Handler.postDelayed(Runnable, delay)
在短暂延迟后触发“关闭”动画。然而,在打开和关闭之间的时间内,可能会因为点击触发另一个动画。
我的问题是,我该如何在处理程序中取消“关闭”动画?
我有一个“打开”动画,并使用Handler.postDelayed(Runnable, delay)
在短暂延迟后触发“关闭”动画。然而,在打开和关闭之间的时间内,可能会因为点击触发另一个动画。
我的问题是,我该如何在处理程序中取消“关闭”动画?
只需使用 removeCallbacks(Runnable r)
方法。
Cristian的回答是正确的,但与回答评论所述的相反,您实际上可以通过调用removeCallbacksAndMessages(null);
来删除匿名Runnables
的回调。
正如这里所述:
删除任何待处理的回调和已发送的消息,其obj为令牌。如果令牌为null,则将删除所有回调和消息。
Handler
或View
类时,这种行为是不同的。在一个View
类中(也许从4.0开始?),你必须使用相同的Runnable
对象来取消任务,而对于一个Handler
类,如果你传递null
,它们将被全部取消。尽管如此,问题中指定了一个Handler
,所以你的答案是正确的。 - Andre虽然回答晚了,但是这里有一种不同的方法可以仅从处理程序中删除特定类别的可运行对象(即在 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()),因此最好使用整数/ Integer 而不是字符串作为令牌。
string
改成了 int
,然后我就有了这个 bug 一整天 :D https://stackoverflow.com/q/62405834/2736039 - Ultimo_mpublic 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并禁用倒计时。对于使用递归的人来说,这很有用,但我是通过搜索找到这里的,所以我发布了我的结果。