使用处理程序循环遍历数据

时间:2015-03-09 00:04:47

标签: android timer handler

我正在尝试开发一种方法,该方法将循环遍历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个小时来完全调试和研究这个中间循环延迟。任何帮助将不胜感激!

1 个答案:

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