Search code examples
javaandroidcountdowntimer

Change Color everysecond AndroidStudio


Hello again guys firstly i am new at android studio.i am trying to make countdowntimer and i made it its working

then i want to make change background color every tick , every second.

thank you!

    new CountDownTimer(3000, 1000) {
        @Override
        public void onTick(long millisUntilFinished) {
            getWindow().getDecorView().setBackgroundColor(Color.WHITE);
            String text = String.format(Locale.getDefault(), " %02d:%02d",
                    TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) % 60,
                    TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) % 60);
            textView.setText(text);
            getWindow().getDecorView().setBackgroundColor(Color.RED);


        }

        @Override
        public void onFinish() {
            textView.setTextSize(20);
            textView.setText("done.");
            getWindow().getDecorView().setBackgroundColor(Color.rgb(0, 153, 51));

        }
    }.start();

Solution

  • The problem lies in the fact that on each tick you are setting the background color to white and then immediately to red, inside onTick. This will most likely result for the user to not be able to see the white color, because it is immediately overwritten on every tick. You need a way to change to a single color for each tick.

    Don't forget to always run UI related code on the UI thread. You can read more about on how to do it here.

    In case you want to alternate between white color and red for every tick, then you can have a flag in your CountDownTimer like so:

    new CountDownTimer(10000, 1000) {
        private boolean white = true;
    
        @Override
        public void onTick(final long millisUntilFinished) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    final int color;
                    if (white) //Select color depending on flag's value:
                        color = Color.WHITE;
                    else
                        color = Color.RED;
                    white = !white; //Flip the flag.
                    getWindow().getDecorView().setBackgroundColor(color);
                    String text = String.format(Locale.getDefault(), " %02d:%02d",
                            TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) % 60,
                            TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) % 60);
                    textView.setText(text);
                }
            });
        }
    
        @Override
        public void onFinish() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    textView.setTextSize(20);
                    textView.setText("done.");
                    getWindow().getDecorView().setBackgroundColor(Color.rgb(0, 153, 51));
                }
            });
        }
    }.start();
    

    Or better, you can rely on the value millisUntilFinished which is given as the single argument to onTick, like so:

    final long total = 10000, interval = 1000;
    new CountDownTimer(total, interval) {
        @Override
        public void onTick(final long millisUntilFinished) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    final long millisElapsed = total - millisUntilFinished;
                    final int color;
                    if ((millisElapsed / interval) % 2 == 0)
                        color = Color.WHITE;
                    else
                        color = Color.RED;
                    getWindow().getDecorView().setBackgroundColor(color);
                    String text = String.format(Locale.getDefault(), " %02d:%02d",
                            TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) % 60,
                            TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) % 60);
                    textView.setText(text);
                }
            });
        }
    
        @Override
        public void onFinish() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    textView.setTextSize(20);
                    textView.setText("done.");
                    getWindow().getDecorView().setBackgroundColor(Color.rgb(0, 153, 51));
                }
            });
        }
    }.start();
    

    This approach should be better because if I understand correctly from the documentation of CountDownTimer, it seems that the millisUntilFinished (given in onTick) is not guaranteed to be a multiple of the interval, which would depend also on the amount of work the onTick method is doing.