如何在机器人中设置延迟?

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;


}
}

我想设置一个延迟之间的命令更改背景。我尝试使用线程计时器,并尝试使用 run 和 catch。但是没有用。我试过了

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

但只是换成了黑色。

402569 次浏览

试试这个代码:

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

使用 Thread.sleep(millis)方法。

您可以使用 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();

如果你想在用户界面中按照固定的时间间隔做一些事情,使用 CountDownTimer 是一个很好的选择:

new CountDownTimer(30000, 1000) {


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


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

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

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


}
});

你可以用这个:

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秒。

Kotlin 的管理者回答:

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

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

2-然后把它称为任何你需要它的地方:

delayFunction({ myDelayedFunction() }, 300)

这里有一个例子,我改变背景图像从一个到另一个与2秒阿尔法淡出延迟两种方式-2s 淡出的原始图像到2s 淡出到第二个图像。

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

我认为到2020年最简单、最稳定、最有用的方法是使用 协奏曲delay函数代替 Runnable 函数。协同程序是处理异步作业的一个很好的概念,它的 delay组件将是这个问题的重点。

警告: 协同程序需要 abc 0语言,我没有把代码转换成 Kotlin 语言,但我认为每个人都能理解其中的主要概念。.

只要在你的 build.gradle上加上 Coroutines:

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

向你的类(活动、片段或其他东西)添加一个你将在其中使用协程的作业:

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

通过使用 发射主体,可以在类上使用 Coroutines 任何地方。所以你可以这样写代码:

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{}函数是 异步的,如果你这样写的话,循环不会等到 delay函数完成:

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

因此,如果您想让所有 for 循环等待 delay,那么 launch{ }应该覆盖 for 循环。

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

package com.viraj.myamppractice;


import androidx.appcompat.app.AppCompatActivity;


import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;


import java.util.Random;


public class Question6 extends AppCompatActivity {


TextView diceop;
Button roll;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_question6);


roll = findViewById(R.id.rollButton);
diceop = findViewById(R.id.opDice);
Thread timer = new Thread(){
@Override
public void run() {
try {
Thread.sleep(5000);
Random no = new Random();
int number = no.nextInt(6)+1;
String str = String.valueOf(number);


diceop.setText(str);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};


roll.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {


timer.run();




}
});




}
}