我正在尝试开发一种方法,该方法将循环遍历String变量并根据每个字符更改背景颜色,延迟一秒,以便用户可以观察每种颜色。我已经研究了类似的问题,大多数答案都推荐使用Handlers()或Timers(),因为不推荐使用UI线程。
我遇到的问题是Handler方法和Timer方法都创建Runnables或TimerTasks,并且我不能发送我的循环迭代器的int值而不将其声明为最终变量,阻止我递增到字符串的下一个字母。
public void replayPattern(View view){
int i=0;
String temp;
int delay = 1000;
RelativeLayout myGameLayout = (RelativeLayout) findViewById(R.id.game_RelativeLayout);
TextView display = (TextView) findViewById(R.id.display);
display.setText("Replaying the pattern...");
myGameLayout.setBackgroundColor(this.getResources().getColor(R.color.white));
while(i < pattern.length()){
temp = pattern.substring(i, i+1);
if(temp.equals("r")){
//Toast.makeText(getApplicationContext(), temp, Toast.LENGTH_SHORT).show();
myGameLayout.setBackgroundColor(this.getResources().getColor(R.color.game_red));
}
else if(temp.equals("b")){
//Toast.makeText(getApplicationContext(), temp, Toast.LENGTH_SHORT).show();
myGameLayout.setBackgroundColor(this.getResources().getColor(R.color.game_blue));
}
else if(temp.equals("y")){
//Toast.makeText(getApplicationContext(), temp, Toast.LENGTH_SHORT).show();
myGameLayout.setBackgroundColor(this.getResources().getColor(R.color.game_yellow));
}
else{
// error, should not occur
myGameLayout.setBackgroundColor(this.getResources().getColor(R.color.white));
Toast.makeText(getApplicationContext(), "Error, character not recognized: " + temp, Toast.LENGTH_SHORT).show();
}
i++;
// WAIT 1 SECOND, SO USER CAN OBSERVE COLOR PATTERN
}
myGameLayout.setBackgroundColor(this.getResources().getColor(R.color.white));
display.setText("");
}
我能找到的最流行的答案出现在这里(How to call a method after a delay in Android),我试图在下面实施:
public void replayPattern2(View view){
int i=0;
//String temp;
int delay = 1000;
//RelativeLayout myGameLayout = (RelativeLayout) findViewById(R.id.game_RelativeLayout);
//TextView display = (TextView) findViewById(R.id.display);
display.setText("Replaying the pattern...");
myGameLayout.setBackgroundColor(this.getResources().getColor(R.color.white));
final Handler handler = new Handler();
patternIndex = 0;
while(patternIndex < pattern.length()-1){
handler.postDelayed(new Runnable() {
@Override
public void run() {
runCount++;
String temp = pattern.substring(patternIndex, patternIndex+1);
if(temp.equals("r")){
Toast.makeText(getApplicationContext(), temp, Toast.LENGTH_SHORT).show();
myGameLayout.setBackgroundColor(getResources().getColor(R.color.game_red));
}
else if(temp.equals("b")){
Toast.makeText(getApplicationContext(), temp, Toast.LENGTH_SHORT).show();
myGameLayout.setBackgroundColor(getResources().getColor(R.color.game_blue));
}
else if(temp.equals("y")){
Toast.makeText(getApplicationContext(), temp, Toast.LENGTH_SHORT).show();
myGameLayout.setBackgroundColor(getResources().getColor(R.color.game_yellow));
}
else{
// error, should not occur
myGameLayout.setBackgroundColor(getResources().getColor(R.color.green));
Toast.makeText(getApplicationContext(), "Error, character not recognized: " + temp, Toast.LENGTH_SHORT).show();
}
}
}, delay);
patternIndex++;
}
//myGameLayout.setBackgroundColor(this.getResources().getColor(R.color.white));
display.setText("runcount = " + runCount);
}
从我可以观察到的,代码实际上是通过正确数量的循环,但它仍然没有在迭代之间实际暂停并显示中间颜色变化。我可能还有一点点缺失,但是我花了将近12个小时来完全调试和研究这个中间循环延迟。任何帮助将不胜感激!
答案 0 :(得分:0)
你的replayPattern2()函数不起作用的原因是,即使你发布Runnable
有延迟,你的for循环也没有任何延迟,然后再转到下一个字符并且发布下一个Runnable
,这样您就可以在计划开始后的1000毫秒内安排所有Runnables
计划一个接一个地运行。
您可以修改Runnable
以使其运行,然后在完成时将其自身发回Handler
,并检查String
的结尾。一开始你只需要发布一个Runnable
,这样你就可以摆脱for循环:
final int delay = 1000; // delay needs to be declared final to access it inside the Runnable
final Handler handler = new Handler();
patternIndex = 0;
handler.postDelayed(new Runnable() {
@Override
public void run() {
runCount++;
String temp = pattern.substring(patternIndex, patternIndex+1);
if(temp.equals("r")){
Toast.makeText(getApplicationContext(), temp, Toast.LENGTH_SHORT).show();
myGameLayout.setBackgroundColor(getResources().getColor(R.color.game_red));
}
else if(temp.equals("b")){
Toast.makeText(getApplicationContext(), temp, Toast.LENGTH_SHORT).show();
myGameLayout.setBackgroundColor(getResources().getColor(R.color.game_blue));
}
else if(temp.equals("y")){
Toast.makeText(getApplicationContext(), temp, Toast.LENGTH_SHORT).show();
myGameLayout.setBackgroundColor(getResources().getColor(R.color.game_yellow));
}
else{
// error, should not occur
myGameLayout.setBackgroundColor(getResources().getColor(R.color.green));
Toast.makeText(getApplicationContext(), "Error, character not recognized: " + temp, Toast.LENGTH_SHORT).show();
}
patternIndex++;
if(patternIndex <= pattern.length()-1)
handler.postDelayed(this, delay); // the Runnable posts itself to the Handler if not at the end of the string yet
}
}, delay);