Vaibhav Maheshwari
Vaibhav Maheshwari

Reputation: 384

Repeating the process : displaying a view for an random time then make it invisible for an random time

The title says it all. I want to make a view into an infinite loop of random visibility and invisibility. This is how I approached it :-

First I created two methods to get Random time getRandomWaitTime() and getRandomDisplayTime(). These methods are well defined and tested (in Log) and are working as desired. Both these methods return a random value as int in millisecond as

getRandomWaitTime()     :   3000-6000
getRandomDisplayTime()  :   3000-5000

Now I created one ImageView fruit[0], set it initially as invisible and after that the following code is executed :

fruit[0].postDelayed(new Runnable() {
            @Override
            public void run() {
                fruit[0].setVisibility(View.VISIBLE);
                fruit[0].postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        fruit[0].setVisibility(View.INVISIBLE);
                    }
                }, getRandomDisplayTime());
                fruit[0].postDelayed(this, getRandomWaitTime());
                }
        }, getRandomWaitTime()); 

The code compiles, executes as well, the ImageView goes through infinite cycle of visibility and invisibility but the time for which it is set as visible or invisible doesn't seem to have minimum value of 3000ms Sometimes it feels like it is visible for a 500ms and then gone invisible. I have tried a ton of things such as using Handler.postDelayed instead of View.postDelayed but this doesn't seem to work.

Interesting thing happens when I remove all getRandomWaitTime() and getRandomDisplayTime() methods from postDelayed method and replace then with a constant like 3000.

The activity starts. At first fruit[0] is set to invisible. After 3000ms it comes visible and stays there. Nothing happens after it. No more switching to invisibility. I just stays there.

So what could be the possible reasons for all these sorcery problems?

Upvotes: 2

Views: 75

Answers (2)

gi097
gi097

Reputation: 7701

Your code is a bit messy, try this example. Based on the view itself, values will be chosen instead of nested postDelayed() methods.

fruit[0].postDelayed(new Runnable() {
    @Override
    public void run() {
        fruit[0].setVisibility(backButton.getVisibility() == View.VISIBLE ? View.INVISIBLE : View.VISIBLE);
        fruit[0].postDelayed(this, backButton.getVisibility() == View.VISIBLE ? getRandomDisplayTime() : getRandomWaitTime());
    }
}, fruit[0].getVisibility() == View.VISIBLE ? getRandomDisplayTime() : getRandomWaitTime());

Upvotes: 2

GVillani82
GVillani82

Reputation: 17429

The point is that, after the first you call fruit[0].setVisibility(View.VISIBLE);:

fruit[0].postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        fruit[0].setVisibility(View.INVISIBLE);
                    }
                }, getRandomDisplayTime());

and:

fruit[0].postDelayed(this, getRandomWaitTime());

are executed almost at the same time (immediately).

So, let's say for example the getRandomDisplayTime() return 3000 and getRandomWaitTime() returns 3500, you will see the view visible after 3000 milliseconds and after 500 milliseconds more, it will disappear again.

You can change your code in this way:

fruit[0].postDelayed(new Runnable() {
            @Override
            public void run() {
                final Runnable runnable = this;
                fruit[0].setVisibility(View.VISIBLE);
                fruit[0].postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        fruit[0].setVisibility(View.INVISIBLE);
                        fruit[0].postDelayed(runnable, getRandomWaitTime());
                    }
                }, getRandomDisplayTime());
            }
        }, getRandomWaitTime());

Upvotes: 2

Related Questions