Reputation: 384
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
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
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