使用处理程序循环遍历数据
Using Handlers to loop through data
我正在尝试开发一种方法,该方法将循环遍历字符串变量并根据每个字符更改背景颜色,延迟一秒,以便用户可以观察到每种颜色。我研究过类似的问题,大多数答案都推荐 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 个小时来调试和研究这个中间循环延迟。任何帮助将不胜感激!
你的 replayPattern2() 函数不工作的原因是即使你 post Runnable
有延迟,在移动之前你的 for 循环没有任何延迟到下一个字符并 post 进入下一个 Runnable
,因此您最终会在程序开始 1000 毫秒后将所有 Runnables
安排到一个接一个 运行。
您可以修改 Runnable
,使其 运行s 然后 posts 自己回到 Handler
并在完成时延迟,检查String
结束。一开始你只需要post一个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);
我正在尝试开发一种方法,该方法将循环遍历字符串变量并根据每个字符更改背景颜色,延迟一秒,以便用户可以观察到每种颜色。我研究过类似的问题,大多数答案都推荐 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 个小时来调试和研究这个中间循环延迟。任何帮助将不胜感激!
你的 replayPattern2() 函数不工作的原因是即使你 post Runnable
有延迟,在移动之前你的 for 循环没有任何延迟到下一个字符并 post 进入下一个 Runnable
,因此您最终会在程序开始 1000 毫秒后将所有 Runnables
安排到一个接一个 运行。
您可以修改 Runnable
,使其 运行s 然后 posts 自己回到 Handler
并在完成时延迟,检查String
结束。一开始你只需要post一个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);