如何从 postDelayed 添加的处理程序对象中删除可运行对象?

发布于 2024-09-17 01:32:22 字数 205 浏览 14 评论 0原文

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

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

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.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

爱你是孤单的心事 2024-09-24 01:32:23

这是一个迟来的答案,但是当您只想从处理程序中删除特定类别的可运行对象时(即在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()),因此最好使用整数/整数而不是字符串作为标记。

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

    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.

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.

_失温 2024-09-24 01:32:23

如果您使用递归,您可以通过传递“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 并禁用倒计时。这仅对使用递归的人有用,但我来到这里寻找递归,所以我发布了我的结果。

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

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.

若言繁花未落 2024-09-24 01:32:23

如果您使用匿名可运行对象,您可以将其与令牌对象配对,以便稍后将其删除。

private void postDelayedRunnable(@NonNull Runnable runnable, @NonNull Object token, long delayMillis) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        mHandler.postDelayed(runnable, token, delayMillis);
    } else {
        Message msg = Message.obtain(mHandler, runnable);
        msg.obj = token;
        mHandler.sendMessageDelayed(msg, delayMillis);
    }
}

要删除它,您需要相同的令牌,只需调用

mHandler.removeCallbacksAndMessages(token);

警告:将使用 == 而不是 .equals 方法来比较令牌。最好不要使用原始数据类型,请参阅:未删除令牌类型 Int 或 Long (*Kotlin) 的 Android 处理程序回调

If you are using an anonymous runnable you could pair it with a token object to be able to remove it later.

private void postDelayedRunnable(@NonNull Runnable runnable, @NonNull Object token, long delayMillis) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        mHandler.postDelayed(runnable, token, delayMillis);
    } else {
        Message msg = Message.obtain(mHandler, runnable);
        msg.obj = token;
        mHandler.sendMessageDelayed(msg, delayMillis);
    }
}

and to remove it you need the same token and just call

mHandler.removeCallbacksAndMessages(token);

WARNING: the token will be compared using == and not the .equals method. Better not use primitive data types, see: Android Handler callback not removed for token type Int or Long (*Kotlin)

待天淡蓝洁白时 2024-09-24 01:32:22

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

如所述此处

删除任何 obj 为 token 的待处理回调帖子和已发送消息。 如果 token 为 null,则所有回调和消息都将被删除

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文