Question

I have a list of hex colors with a duration in milliseconds for each one. I would like to fill the screen with each color for its duration, then move on to the next color.

I tried to iterate over the colors to do the following:

 myView.setBackgroundColor(Color.parseColor( theColor ));
 SystemClock.sleep( theDuration );

 myView.setBackgroundColor(Color.parseColor( nextColor ));
 SystemClock.sleep( nextDuration );

 etc...

which seemed obvious to me but doesn't do anything to the view when it's running, at least in my AVD. I'm learning that it's because Android only draws at predefined times. (I tried calling "Invalidate()" as well with no luck.)

What is the best way to display all the colors consecutively?

(I realize I shouldn't be calling sleep() either, so any suggestions for that would also be appreciated.)

Thanks.

Was it helpful?

Solution 3

I ended up creating a Runnable inside the my button click event handler. Everything (looping through the colors and durations plus "sleeping" based on the durations) is done in the Runnable run() method.

public void playOnClick(View v) {
    Runnable runnable = new Runnable() {
        public void run() {
            ...
        }

Then I created a handler inside my UI Activity class that just changes the color of the background.

Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        Bundle b = msg.getData();
        String theColor = b.getString("color");

        myView = (View) findViewById(R.id.bigView);
        myView.setBackgroundColor(Color.parseColor(theColor));
    }
};

Inside the run() method, he Runnable sends a message to the handler containing the background color using Bundle/Message objects:

b = new Bundle();
b.putString("color", theColor);
msg = new Message();
msg.setData(b);
handler.sendMessage(msg);

OTHER TIPS

new Thread() {
    @Override
    public void run() {
        YourActivity.this.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            myView.setBackgroundColor(Color.parseColor( theColor ));
        }
        Thread.sleep( theDuration);

        YourActivity.this.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            myView.setBackgroundColor(Color.parseColor( nextColor ));
        }
        Thread.sleep( nextDuration );
    }
}.start();

Put this in a method and call it.

There are many ways to achieve what you want. One could be to use Handler and Runnable. Assuming you know how to get current color and duration, you could do:

  • declare Runnable as class variable

    private Runnable runnable = null;
    
  • inside onCreate(), after you set initial view, initialise Handler

    final Handler handler = new Handler();
    
  • initialise runnable and change the background in run() method

    runnable = new Runnable() {
        @Override
        public void run() {
            //change the color
            myView.setBackgroundColor(currentColor);
    
            //run it again in nextDuration miliseconds
            handler.postDelayed(toggle, nextDuration);
        }
    };
    
    //start runnable in theDuration miliseconds
    handler.postDelayed(toggle, theDuration);
    

You could have arrays of colors and durations and cycle through them with index variable. This is assuming that myView is a valid view.

EDIT:

To those who downvoted, read the documentation for Handler:

When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it...

In other words, you are creating a handler in onCreate() of your activity, so it will be able to update your view.

This blogpost from adroid-developers website uses very similar construct as proposed above.

The Handler runs the update code as a part of your main thread, avoiding the overhead of a second thread and also making for easy access to the View hierarchy used for the user interface.

See here and here answered by CommonsWare and here - answered by Laith Alnagem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top