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

        }
    }

我想在更改背景之间的命令之间设置延迟。我尝试使用线程计时器并尝试使用运行和捕获。但它不起作用。我试过这个

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

但它只会变成黑色。

4

9 回答 9

572

试试这个代码:

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);
于 2013-04-08T08:06:55.713 回答
46

您可以使用CountDownTimer比发布的任何其他解决方案更有效的方法。onTick(long)您还可以使用其方法定期生成定期通知

看看这个显示 30 秒倒计时的例子

   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();
于 2015-01-27T11:30:00.060 回答
26

如果您在应用程序中经常使用延迟,请使用此实用程序类

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

用法:

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

    }
});
于 2016-03-19T19:01:56.460 回答
22

使用Thread.sleep(millis)方法。

于 2013-04-11T13:25:35.533 回答
7

如果您想定期在 UI 中执行某些操作,那么非常好的选择是使用 CountDownTimer:

new CountDownTimer(30000, 1000) {

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

     public void onFinish() {
         mTextField.setText("done!");
     }
  }.start();
于 2015-11-02T13:30:49.623 回答
5

Kotlin 中的处理程序回答:

1 - 在文件中创建一个顶级函数(例如一个包含所有顶级函数的文件):

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

2 - 然后在您需要的任何地方调用它:

delayFunction({ myDelayedFunction() }, 300)
于 2018-10-02T06:53:41.887 回答
4

你可以使用这个:

import java.util.Timer;

对于延迟本身,添加:

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

其中delay变量以毫秒为单位;例如设置delay为 5000 延迟 5 秒。

于 2018-08-07T20:47:36.433 回答
0

这是一个示例,其中我将背景图像从一个更改为另一个,双向具有 2 秒的 alpha 渐变延迟 - 原始图像的 2 秒淡出到第二个图像的 2 秒淡入。

    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);
        }
    });
}
于 2019-01-03T00:02:51.963 回答
0

我认为截至 2020 年最简单、最稳定、最有用的方法是使用Coroutinesdelay的功能而不是 Runnable。协程是处理异步作业的一个很好的概念,它的组件将是这个答案的重点。delay

警告:协程需要Kotlin语言,我没有将代码转换为 Kotlin,但我认为每个人都能理解主要概念。

只需将协程添加到您的build.gradle

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'

向您的课程(活动、片段或其他内容)添加一个作业,您将在其中使用协程:

private var job: Job = Job()
override val coroutineContext: CoroutineContext
    get() = Dispatchers.Main + job

您可以使用launch{ } body在类的任何地方使用协程。所以你可以这样写你的代码:

public void onClick(View v) {

    launch {

        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);
                        delay(2000)
                        buttons[inew][jnew].setBackgroundColor(Color.WHITE);
                        break;
                    }
                }
        }
            break;

        }
    }
}

都是...

不要忘记launch{}函数是异步的,如果你这样写,for循环不会等待函数完成:delay

launch{
    buttons[inew][jnew].setBackgroundColor(Color.BLACK);
    delay(2000)
    buttons[inew][jnew].setBackgroundColor(Color.WHITE);
}

因此,launch{ }如果您希望所有 for 循环等待,则应覆盖 for 循环delay

另一个好处launch{ }是您正在使 for 循环异步,这意味着它不会在繁重的进程上阻塞应用程序的主 UI 线程。

于 2020-09-28T14:53:45.920 回答