¿Cómo configurar el retraso en Android?

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

        }
    }

Quiero establecer un retraso entre el comando entre cambiar el fondo. Intenté usar un temporizador de hilo e intenté usar ejecutar y atrapar. Pero no está funcionando. Probé esto

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

Pero solo se está cambiando a negro.

Kenneth Joseph Paul
fuente

Respuestas:

499

Prueba este código:

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);
Tuan Vu
fuente
1
Esta solución explicó todas las preguntas que tenía con los controladores en algunas líneas de código.
Sierisimo
45
Siempre vuelvo a esta publicación porque soy demasiado vago para escribirla cada vez. Gracias.
Eugene H
bueno, llok agradable, pero tengo muchos mensajes para esperar y luego mostrar. así que las huellas múltiples dan problema. ¿Cómo se puede resolver el problema de múltiples pasos
Mehmet
2
Esta solución produce una pérdida de memoria porque utiliza una clase interna y anónima no estática que implícitamente contiene una referencia a su clase externa, la actividad. Ver stackoverflow.com/questions/1520887/… para una mejor solución.
tronman
@EugeneH Use plantillas en vivo para una vida más fácil stackoverflow.com/a/16870791/4565796
Saeed Arianmanesh
38

Puede usar CountDownTimercuál es mucho más eficiente que cualquier otra solución publicada. También puede generar notificaciones regulares en intervalos a lo largo del camino utilizando suonTick(long) método

Eche un vistazo a este ejemplo que muestra una cuenta regresiva de 30 segundos

   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();
Sufiyan Ghori
fuente
23

Si usa retraso con frecuencia en su aplicación, use esta clase de utilidad

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.
    }
}

Uso:

// 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

    }
});
aruke
fuente
1
Por qué ? Esto es pura sobrecarga y complejidad ... para nada
juloo65
Si usamos retrasos frecuentes, entonces está bien tener un formato fijo para los retrasos. No creo que haya mucha sobrecarga debido a una interfaz adicional y un método.
Aruke
18

Usando el Thread.sleep(millis)método.

usuario2270457
fuente
30
no haga esto en el hilo de interfaz de usuario - otros elementos también pueden dejar de responder y luego comportarse de forma impredecible
jmaculate
1
gracias por la advertencia. eso es exactamente lo que necesito, para retrasar el hilo de la interfaz de usuario. respuesta perfecta para mis necesidades Gracias.
hamish
7

Si desea hacer algo en la interfaz de usuario en intervalos de tiempo regulares, una muy buena opción es usar CountDownTimer:

new CountDownTimer(30000, 1000) {

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

     public void onFinish() {
         mTextField.setText("done!");
     }
  }.start();
Ivo Stoyanov
fuente
Es más limpio que el Handler .
Ahsan el
3

Respuesta del controlador en Kotlin:

1 - Cree una función de nivel superior dentro de un archivo (por ejemplo, un archivo que contenga todas sus funciones de nivel superior):

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

2 - Luego llámalo donde lo necesites:

delayFunction({ myDelayedFunction() }, 300)
Phil
fuente
2

Puedes usar esto:

import java.util.Timer;

y para el retraso en sí, agregue:

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

donde la delayvariable está en milisegundos; por ejemplo establecido delayen 5000 para un retraso de 5 segundos.

Dror
fuente
0

Aquí hay un ejemplo en el que cambio la imagen de fondo de una a otra con un retraso de desvanecimiento alfa de 2 segundos en ambos sentidos: desvanecimiento de 2 segundos de la imagen original en un desvanecimiento de 2 segundos en la segunda imagen.

    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);
        }
    });
}
MuharizJ
fuente