Comment définir le retard dans Android?


165
public void onClick(View v) {
        // TODO Auto-generated method stub
        switch(v.getId()){
        case R.id.rollDice:
            Random ranNum = new Random();
            int number = ranNum.nextInt(6) + 1;
            diceNum.setText(""+number);
            sum = sum + number;
            for(i=0;i<8;i++){
                for(j=0;j<8;j++){

                    int value =(Integer)buttons[i][j].getTag();
                    if(value==sum){
                        inew=i;
                        jnew=j;

                        buttons[inew][jnew].setBackgroundColor(Color.BLACK);
                                                //I want to insert a delay here
                        buttons[inew][jnew].setBackgroundColor(Color.WHITE);
                         break;                     
                    }
                }
            }


            break;

        }
    }

Je veux définir un délai entre la commande entre le changement d'arrière-plan. J'ai essayé d'utiliser un minuteur de fil et j'ai essayé d'utiliser run and catch. Mais ça ne marche pas. J'ai essayé ça

 Thread timer = new Thread() {
            public void run(){
                try {
                                buttons[inew][jnew].setBackgroundColor(Color.BLACK);
                    sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

             }
           };
    timer.start();
   buttons[inew][jnew].setBackgroundColor(Color.WHITE);

Mais il ne fait que devenir noir.

Réponses:


501

Essayez ce code:

import android.os.Handler;
...
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        // Do something after 5s = 5000ms
        buttons[inew][jnew].setBackgroundColor(Color.BLACK);
    }
}, 5000);

1
Cette solution a expliqué toutes les questions que j'avais avec les gestionnaires à certaines lignes de code.
— Sierisimo

45
Je reviens toujours sur ce post car je suis trop paresseux pour l'écrire à chaque fois. Je vous remercie.
— Eugene H

Eh bien, ça va bien mais j'ai beaucoup de message à attendre puis à montrer. donc les bandes de roulement multiples posent problème. comment peut résoudre le problème de plusieurs bandes de roulement
— mehmet

2
Cette solution produit une fuite de mémoire car elle utilise une classe interne et anonyme non statique qui contient implicitement une référence à sa classe externe, l'activité. Voir stackoverflow.com/questions/1520887/… pour une meilleure solution.
— tronman

@EugeneH Utilisez des modèles en direct pour une vie plus facile stackoverflow.com/a/16870791/4565796
— Saeed Arianmanesh

38

Vous pouvez utiliser CountDownTimerce qui est beaucoup plus efficace que toute autre solution publiée. Vous pouvez également produire des notifications régulières à intervalles réguliers en utilisant sa onTick(long)méthode

Jetez un œil à cet exemple montrant un compte à rebours de 30 secondes

   new CountDownTimer(30000, 1000) {
         public void onFinish() {
             // When timer is finished 
             // Execute your code here
     }

     public void onTick(long millisUntilFinished) {
              // millisUntilFinished    The amount of time until finished.
     }
   }.start();

23

Si vous utilisez fréquemment le délai dans votre application, utilisez cette classe d'utilitaire

import android.os.Handler;


public class Utils {

    // Delay mechanism

    public interface DelayCallback{
        void afterDelay();
    }

    public static void delay(int secs, final DelayCallback delayCallback){
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                delayCallback.afterDelay();
            }
        }, secs * 1000); // afterDelay will be executed after (secs*1000) milliseconds.
    }
}

Usage:

// Call this method directly from java file

int secs = 2; // Delay in seconds

Utils.delay(secs, new Utils.DelayCallback() {
    @Override
    public void afterDelay() {
        // Do something after delay

    }
});

1
Pourquoi ? C'est une pure surcharge et complexité ... pour rien
— juloo65

Si nous utilisons des retards fréquents, alors avoir un format fixe pour les retards est très bien. Je ne pense pas qu'il y ait beaucoup de frais généraux à cause d'une interface et d'une méthode supplémentaires.
— aruke

18

En utilisant la Thread.sleep(millis)méthode.


30
ne faites pas cela sur le thread de l'interface utilisateur - d'autres éléments peuvent également cesser de répondre et se comporter plus tard de manière imprévisible
— jmaculate

1
merci pour l'avertissement. c'est exactement ce dont j'ai besoin, pour retarder le thread de l'interface utilisateur. réponse parfaite à mes besoins. Merci.
— hamish

7

Si vous voulez faire quelque chose dans l'interface utilisateur à des intervalles de temps réguliers, une très bonne option est d'utiliser CountDownTimer:

new CountDownTimer(30000, 1000) {

     public void onTick(long millisUntilFinished) {
         mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
     }

     public void onFinish() {
         mTextField.setText("done!");
     }
  }.start();

C'est plus propre que le Handler .
— Ahsan

3

Réponse du gestionnaire à Kotlin:

1 - Créez une fonction de niveau supérieur dans un fichier (par exemple un fichier contenant toutes vos fonctions de niveau supérieur):

fun delayFunction(function: ()-> Unit, delay: Long) {
    Handler().postDelayed(function, delay)
}

2 - Ensuite, appelez-le partout où vous en avez besoin:

delayFunction({ myDelayedFunction() }, 300)

2

Vous pouvez utiliser ceci:

import java.util.Timer;

et pour le retard lui-même, ajoutez:

 new Timer().schedule(
                    new TimerTask(){
                
                        @Override
                        public void run(){
                            
                        //if you need some code to run when the delay expires
                        }
                        
                    }, delay);

où la delayvariable est en millisecondes; par exemple réglé delaysur 5000 pour un délai de 5 secondes.


0

Voici un exemple où je change l'image d'arrière-plan de l'une à l'autre avec un délai de fondu alpha de 2 secondes dans les deux sens - un fondu de 2s de l'image d'origine en un fondu de 2s dans la 2ème image.

    public void fadeImageFunction(View view) {

    backgroundImage = (ImageView) findViewById(R.id.imageViewBackground);
    backgroundImage.animate().alpha(0f).setDuration(2000);

    // A new thread with a 2-second delay before changing the background image
    new Timer().schedule(
            new TimerTask(){
                @Override
                public void run(){
                    // you cannot touch the UI from another thread. This thread now calls a function on the main thread
                    changeBackgroundImage();
                }
            }, 2000);
   }

// this function runs on the main ui thread
private void changeBackgroundImage(){
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            backgroundImage = (ImageView) findViewById(R.id.imageViewBackground);
            backgroundImage.setImageResource(R.drawable.supes);
            backgroundImage.animate().alpha(1f).setDuration(2000);
        }
    });
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.