2010-09-02 8 views
62

У меня есть «open» анимация, и я использую Handler.postDelayed(Runnable, delay), чтобы вызвать «закрыть» анимация после короткой задержки. Тем не менее, в течение времени между открытием и закрытием, возможно, есть другая анимация, вызванная щелчком.Как удалить runnable из объекта обработчика, добавленного postDelayed?

Мой вопрос: как я могу отменить «закрыть» анимация в обработчике?

ответ

86

Просто используйте метод removeCallbacks(Runnable r).

+5

Можно ли удалить обратные вызовы для анонимных ходовых файлов? –

+7

Я так не думаю ... вам придется использовать не анонимные. В противном случае вы не сможете ссылаться на них в будущем. – Cristian

+3

См. Ответ @ NameSpace. Вы можете удалить ожидающие запуска, если вы отправляете runnable с помощью токена. Или вы можете использовать метод Daniel L. для удаления всех обратных вызовов/сообщений с использованием нулевого токена. – vman

8

Если вы используете рекурсию, вы можете добиться этого, передав «это». См. Код ниже.

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, он удалит TextView из пользовательского интерфейса и отключит обратный отсчет. Это полезно только для тех, кто использует рекурсию, но я приехал сюда для поиска, поэтому я отправляю свои результаты.

80

ответ Cristian является правильным, но в отличие от того, что указано в комментариях ответить, вы на самом деле можете удалить обратные вызовы для анонимного Runnables по телефону removeCallbacksAndMessages(null);

Как указано here:

Удалить все ожидающие сообщения обратных вызовов и отправленных сообщений, obj - токен. Если токен равен нулю, все обратные вызовы и сообщения будут удалены.

+4

Я хотел бы отметить, что это поведение отличается от того, имеете ли вы дело с классом «Handler» или «View». В классе 'View' (и, возможно, после 4.0?) Вы должны использовать тот же« Runnable »объект для отмены задачи, тогда как с классом« Handler »они просто будут отменены, если вы передадите« null ». Тем не менее, вопрос задает «Обработчик», поэтому ваш ответ правильный. – Andre

+1

действительно !! спасибо .. был какой-то runnable там, и removeCallbacks просто ничего не делал !!!!! но это действительно работает :) thx – cV2

10

Это поздний ответ, но вот другой метод, когда вы только хотите удалить определенную категорию 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); 

Приведенный выше код выполнит «r3», а затем «r4». Это позволяет удалить определенную категорию runnables, определенную вашим токеном, без необходимости хранить ссылки на сами runnables.

Примечание: исходный код сравнивает токены, используя только операнд «==» (он не вызывает .equals()), поэтому лучше всего использовать ints/integers вместо строк для токена.