

以下のコードで数字が格納されたリストからひとつずつ取り出して、反復処理をしています。ところがこのコードを実行するとボタンの色が同時にかわる現象が発生します。

デバッグを実行しステップイン実行するとたしかに反復処理になっているのですが、なぜこのようなことがおこるか全くわかりませんでした。

前回の質問ではThread.sleep()を使用して待機させていたのですが、for文の処理が全て終わってからボタンの色が変わりました。

**今までに試したこと**  
①ハンドラー：ハンドラーを使うと色が同時に変わる  
②timer.scedule(): sceduleも結果は一緒で同時に色が変わる  
③Thread.sleep(): Thread.sleep()を使うとfor文が終了して色が変わる  
④switch文全体をtimer処理しようと思いついたが、ローカル変数をうけとることができない。  
⑤ローカルにアクセスするためにrun()メソッドにfor文を書けばよいと思ったが構文ルールに反するみたい

「色を変える→１秒止まる->また色を変える」とやりたいだけなのですが・・・

よろしくお願いいたします。

[code]

    for(int r : randomList){
        switch (r) {
            case 1:
                button1.setBackgroundColor(Color.BLACK);
                new Handler().postDelayed(new Runnable(){
                    @Override
                    public void run(){
                        button1.setBackgroundColor(Color.WHITE);
                    }
                }, 100);
                break;
            case 2:
                button2.setBackgroundColor(Color.BLACK);
                new Handler().postDelayed(new Runnable(){
                    @Override
                    public void run(){
                        button2.setBackgroundColor(Color.WHITE);
                    }
                }, 100);
                break;
            case 3:
                button3.setBackgroundColor(Color.BLACK);
                new Handler().postDelayed(new Runnable(){
                    @Override
                    public void run(){
                        button3.setBackgroundColor(Color.WHITE);
                    }
                }, 100);
                break;
            case 4:
                button4.setBackgroundColor(Color.BLACK);
                new Handler().postDelayed(new Runnable(){
                    @Override
                    public void run(){
                        button4.setBackgroundColor(Color.WHITE);
                    }
                }, 100);
                break;
        }
    }
    
[/code]


CC BY-SA 4.0
2018-10-01T07:29:37.337
48866
2022-12-27T08:02:15.277
2018-10-01T12:50:38.423
26076
26076
question
android java
Listから取り出したボタンを　1秒まってからボタンの色を変えたい。


**コメントでの助言もあり解決しました（質問者自身による投稿）**

[code]

     for (int r : randomList) {
                        new Handler().postDelayed(new Runnable(){
                            public void run(){
    
                            }
                        }, listCount3);
    
                        switch (r) {
                            case 1:
                                new Handler().postDelayed(new Runnable(){
                                    public void run(){
                                        button1.setBackgroundColor(Color.BLACK);
                                    }
                                }, listCount);
                                new Handler().postDelayed(new Runnable(){
                                    public void run(){
                                        button1.setBackgroundColor(Color.WHITE);
                                    }
                                }, listCount2);
                                break;
                            case 2:
                                new Handler().postDelayed(new Runnable(){
                                    public void run(){
                                        button2.setBackgroundColor(Color.BLACK);
                                    }
                                }, listCount);
                                new Handler().postDelayed(new Runnable() {
                                    public void run() {
                                        button2.setBackgroundColor(Color.WHITE);
                                    }
                                }, listCount2);
                                break;
    
                        }
                        listCount += 500; listCount2 += 500; listCount3 += 500;
                    }
    
[/code]

①postDelayed()メソッドの待機時間に使うためのフィールドを３つ宣言する  
②postDelayed()メソッドの待機時間を全部ずらすことで順番にボタンの色が変わるのを再現。

**解決はしましたが他の方法があれば教えてほしいです**  
C#ではawaitを使用することで簡単に再現できました。javaでawaitに該当するようなものがあればと思うのですが・・・。Thread.Sleep()のように簡単に使えてうまくいくようなメソッドなりがあればと思いました。


CC BY-SA 4.0
2018-10-01T14:54:22.210
48880
2018-10-01T14:54:22.210
26076
48866
answer


await ではありませんが、スレッドを作って `Thread.sleep()` する方法はいかがでしょう。

[code]

        private void stepTest() {
            final int[] randomList = new int[] { 1, 3, 2, 4 };
            final Handler handler = new Handler();
    
            final Button button1 = findViewById(R.id.button1);
            final Button button2 = findViewById(R.id.button2);
            final Button button3 = findViewById(R.id.button3);
            final Button button4 = findViewById(R.id.button4);
    
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    try {
                        for (int r: randomList) {
                            switch (r) {
                            case 1:
                                handler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        button1.setBackgroundColor(Color.BLACK);
                                    }
                                });
                                Thread.sleep(1000);
                                handler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        button1.setBackgroundColor(Color.WHITE);
                                    }
                                });
                                break;
    
                            case 2:
                                handler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        button2.setBackgroundColor(Color.BLACK);
                                    }
                                });
                                Thread.sleep(1000);
                                handler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        button2.setBackgroundColor(Color.WHITE);
                                    }
                                });
                                break;
    
                            case 3:
                                handler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        button3.setBackgroundColor(Color.BLACK);
                                    }
                                });
                                Thread.sleep(1000);
                                handler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        button3.setBackgroundColor(Color.WHITE);
                                    }
                                });
                                break;
    
                            case 4:
                                handler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        button4.setBackgroundColor(Color.BLACK);
                                    }
                                });
                                Thread.sleep(1000);
                                handler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        button4.setBackgroundColor(Color.WHITE);
                                    }
                                });
                                break;
                            }
                        }
                    } catch (InterruptedException e) {
                        android.util.Log.e("StepTest", "interrupted", e);
                    }
                }
            };
    
            Thread thr = new Thread(runnable);
            thr.start();
        }
    
[/code]

ただし、このサンプルには以下の処理がないですが。

  * 処理が終わった頃に、どこかで `thr.join()` する
  * 中断したくなったら、`thr.interrupt()` する


CC BY-SA 4.0
2019-12-06T13:21:11.080
61176
2019-12-06T13:21:11.080
5288
48866
answer