Wie stelle ich die Verzögerung in Android ein?

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

        }
    }

Ich möchte eine Verzögerung zwischen dem Befehl zwischen dem Ändern des Hintergrunds einstellen. Ich habe versucht, einen Thread-Timer zu verwenden und habe Run and Catch verwendet. Aber es funktioniert nicht. Ich habe es versucht

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

Aber es wird nur schwarz.

Kenneth Joseph Paul
quelle

Antworten:

497

Versuchen Sie diesen 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);
Tuan Vu
quelle
1
Diese Lösung erklärte alle Fragen, die ich mit Handlern in einigen Codezeilen hatte.
Sierisimo
43
Ich komme immer wieder auf diesen Beitrag zurück, weil ich zu faul bin, ihn jedes Mal zu schreiben. Danke dir.
Eugene H
Nun, es wird schön, aber ich habe viele Nachrichten zu warten und dann zu zeigen. So geben Multibleiter Probleme. wie kann mehrere Stufen Problem lösen
mehmet
2
Diese Lösung führt zu einem Speicherverlust, da eine nicht statische innere und anonyme Klasse verwendet wird, die implizit einen Verweis auf ihre äußere Klasse, die Aktivität, enthält. Eine bessere Lösung finden Sie unter stackoverflow.com/questions/1520887/… .
Tronman
@ EugeneH Verwenden Sie Live-Vorlagen für ein einfacheres Leben stackoverflow.com/a/16870791/4565796
Saeed Arianmanesh
38

Sie können verwenden, CountDownTimerwas viel effizienter ist als jede andere veröffentlichte Lösung. Mit dieser onTick(long)Methode können Sie auch regelmäßige Benachrichtigungen in Intervallen auf dem Weg erstellen

Schauen Sie sich dieses Beispiel an, das einen Countdown von 30 Sekunden zeigt

   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
quelle
23

Wenn Sie in Ihrer App häufig Verzögerung verwenden, verwenden Sie diese Dienstprogrammklasse

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

Verwendung:

// 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
quelle
1
Warum ? Dies ist purer Aufwand und Komplexität ... für nichts
juloo65
Wenn wir häufige Verzögerungen verwenden, ist es in Ordnung, ein festes Format für Verzögerungen zu haben. Ich glaube nicht, dass es aufgrund einer zusätzlichen Schnittstelle und einer Methode viel Overhead gibt.
Arthur
18

Mit der Thread.sleep(millis)Methode.

user2270457
quelle
30
Tun Sie dies nicht auf dem UI-Thread - andere Elemente reagieren möglicherweise auch nicht mehr und verhalten sich später unvorhersehbar
jmaculate
1
danke für die Warnung. Das ist genau das, was ich brauche, um den UI-Thread zu verzögern. perfekte Antwort für meine Bedürfnisse. Vielen Dank.
Hamish
7

Wenn Sie in regelmäßigen Zeitabständen etwas in der Benutzeroberfläche tun möchten, empfiehlt es sich, CountDownTimer zu verwenden:

new CountDownTimer(30000, 1000) {

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

     public void onFinish() {
         mTextField.setText("done!");
     }
  }.start();
Ivo Stoyanov
quelle
Es ist sauberer als der Handler .
Ahsan
3

Handler Antwort in Kotlin:

1 - Erstellen Sie eine Funktion der obersten Ebene in einer Datei (z. B. eine Datei, die alle Funktionen der obersten Ebene enthält):

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

2 - Rufen Sie es dann an einer beliebigen Stelle an:

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

Sie können dies verwenden:

import java.util.Timer;

und für die Verzögerung selbst fügen Sie hinzu:

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

wo die delayVariable in Millisekunden ist; Zum Beispiel delayfür eine Verzögerung von 5 Sekunden auf 5000 eingestellt .

Dror
quelle
0

Hier ist ein Beispiel, in dem ich das Hintergrundbild mit einer Alpha-Überblendungsverzögerung von 2 Sekunden in beide Richtungen von einem zum anderen ändere - 2s Ausblenden des Originalbilds in 2s Ausblenden in das 2. Bild.

    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
quelle