How to make my app wait in android? [duplicate] - java

This question already has an answer here:
How do you have the code pause for a couple of seconds in android?
(1 answer)
Closed 8 years ago.
In my layout, I have TextViews that are initially set to be invisible. When the user presses the start button, I want one of these TextViews to be visible for .8 seconds. Then I want it to become invisible again and show another TextView for .8 seconds and so on. So basicly, it's like(textView1 pops up for a bit then disappears, then textView2 pops up for a bit then disappears...). There needs to be a good amount of time between each textView. My problem is finding a way to make my code wait a bit in between the:
findViewById(R.id.textView1).setVisibility(00000000); //makes it visible
and
findViewById(R.id.textView1).setVisibility(00000004); //makes it invisible
I have tried many different methods, but most either makes the textView stay invisible, because it gets to the .setVisibility(00000004) to quickly, or it pauses the code, but never seems to become visible as if .setVisibility(00000000) was ignored. This is what I am trying currently, but the textViews stay invisible.
int counter=0;
public void GamePlay(View view)
{
turns[counter]=(int)(4*Math.random()+1);
counter=0;
while(turns[counter]!=0)
{
if(turns[counter]==1)
{
findViewById(R.id.textView1).setVisibility(00000000);
HoldGame();
findViewById(R.id.textView1).setVisibility(00000004);
}
else if(turns[counter]==2)
{
findViewById(R.id.textView2).setVisibility(00000000);
HoldGame();
findViewById(R.id.textView2).setVisibility(00000004);
}
else if(turns[counter]==3)
{
findViewById(R.id.textView3).setVisibility(00000000);
HoldGame();
findViewById(R.id.textView3).setVisibility(00000004);
}
else if(turns[counter]==4)
{
findViewById(R.id.textView4).setVisibility(00000000);
HoldGame();
findViewById(R.id.textView4).setVisibility(00000004);
}
counter++;
}
}
public void HoldGame()
{
Timer timer=new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
}
}, 1*1000);
}

You can try handler class -
Handler handlerTimer = new Handler();
int count = 0;
Runnable runnable = new Runnable(){
public void run() {
if(count==0)
findViewById(R.id.textView1).setVisibility(00000004);
else if(count==1)
findViewById(R.id.textView2).setVisibility(00000004);
else if(count==2)
findViewById(R.id.textView3).setVisibility(00000004);
else if(count==3)
findViewById(R.id.textView4).setVisibility(00000004);
count++;
if(count<4)
handler.postDealyed(runnable, 8000)
}};
Or you can you use ScheduledThreadPoolExecutor
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
int count=0;
scheduler.scheduleAtFixedRate
(new Runnable() {
public void run() {
if(count==0)
findViewById(R.id.textView1).setVisibility(00000004);
else if(count==1)
findViewById(R.id.textView2).setVisibility(00000004);
else if(count==2)
findViewById(R.id.textView3).setVisibility(00000004);
else if(count==3)
findViewById(R.id.textView4).setVisibility(00000004);
count++;
}
}, 0, 8, TimeUnit.SECONDS);
For more information

Related

How to create auto counting code for Android

I want to make an option in my application that if you click a button a counter will start and it will count (like 0++) and show the number until user stops it, so far I have this non working code
if (v == btn3) {
counter = 0;
scoreText.setBackgroundColor(Color.RED);
new Thread(new Runnable() {
public void run() {
while (counter < 1000 ) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
counter++;
}
}
}).start();
scoreText.setText(Integer.toString(counter));
}
Currently when i press the button, the text field only turns red and is set to 0, but I can't make it count
In my opinion setText method is outside loop. It could update text view after loop ends. Move it somewhere inside loop.
This should work as per your needs
if (v == btn3) {
counter = 0;
scoreText.setBackgroundColor(Color.RED);
new Thread(new Runnable() {
public void run() {
while (counter < 1000 ) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
scoreText.setText(Integer.toString(counter));
}
});
counter++;
}
}
}).start();
}
There is a a class called CountDownTimer which provides some useful functionality. In particular it provides an onTick() method with which you could update your text field at a desired interval.
You would need to create a CountDownTimer to count indefinitely, which you can do by restarting the timer in its onFinish() method, like in this question. But if you set the CountDownTimer for long enough, you probably would never need to restart it.
Something like this...
new CountDownTimer(<REALLY_BIG_NUMBER>, 500) {
int counter = 0;
public void onTick(long millisUntilFinished) {
scoreText.setText(counter++);
}
public void onFinish() {
start();
}
}.start();

How do I delay a method in a for loop in java?

I am having trouble delaying the method assign_backgrounds() within a for loop. I am trying to create a Simon says game, but instead of delaying and showing the next button that "Simon" presses, it shows all the buttons at once. Any help here would be greatly appreciated. Thanks.
boolean simonsTurn = true;
int x = 4;
int s;
int delay = 1000;
int array_values[] = new int[]{1,2,3,4};
public void simonSays() {
// running = true;
if (simonsTurn == true) {
go();
for (int i = 0; i < x; i++) {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
go();
}
}, 1000);
}
}
}
public void go(){
s = random_int_between(0,3);
assign_backgrounds(array_values[s]);
}
public void assign_backgrounds( int array_values ){
Handler handler = new Handler();
if( array_values == 1){
button1_.invalidate();
button1_.setBackgroundResource(R.drawable.goatclicked);
button1_.refreshDrawableState();
handler.postDelayed(new Runnable(){
public void run(){
button1_.invalidate();
button1_.setBackgroundResource(R.drawable.goat);
button1_.refreshDrawableState();}}, 1000);
}
else if( array_values == 2){
button2_.invalidate();
button2_.setBackgroundResource(R.drawable.pigclicked);
button2_.refreshDrawableState();
handler.postDelayed(new Runnable(){
public void run(){
button2_.invalidate();
button2_.setBackgroundResource(R.drawable.pig);
button2_.refreshDrawableState();}}, 1000);
}
else if( array_values == 3){
button3_.invalidate();
button3_.setBackgroundResource(R.drawable.chickenclicked);
button3_.refreshDrawableState();
handler.postDelayed(new Runnable() {
public void run() {
button3_.invalidate();
button3_.setBackgroundResource(R.drawable.chicken);
button3_.refreshDrawableState();}}, 1000);
}
if( array_values == 4) {
button4_.invalidate();
button4_.setBackgroundResource(R.drawable.cowclicked);
button4_.refreshDrawableState();
handler.postDelayed(new Runnable(){
public void run(){
button4_.invalidate();
button4_.setBackgroundResource(R.drawable.cow);
button4_.refreshDrawableState();}}, 1000);
}
}
It's because you are creating handlers very fast and then they are all starting at the same time. You should look into how Handler's work and about Asyncronous/Background tasks.
Now back to your problem, you are calling the a loop and it is creating handlers all in a row and they are being created very fast (nanoseconds). They will then all launch 1 second from that creation time because of your postDelayed() call. This is why everything is popping up at the same time! All of these delay posts are being executed at almost the same time on concurrent background threads.
Instead of a for(int i,...) loop you want to have a global int i, just add it to the top of the file.
At the end of any of Simon's turn you'll want, inside of the if, else if statement inside assign_background (at the end of the Runnables, then you'll want to call go().
This might cause problems because you are trying to access the main thread from all these background threads. so you might have to call the function runOnMainUIThread() as a quick hack when you call the go function.
All in all, you are going to have some problems until you understand Handlers, Background Processes, and Threads. Definitely great knowledge to learn about and Android has solid documentation on it just FYI.

Andengine TimerHandler and detecting collisions

I'm developing a game where LittleMan can move from block to block, and certain blocks are moving. I'm trying to detect when he moves to a new moving block, if that block is beneath him or if it has moved. I'm using Andengine's TimerHandler to check every 0.1 seconds but it is not working. Here's the code:
private void OnMovingBlock(final int CurrentPosRow, final int CurrentPosColumn) {
this.getEngine().registerUpdateHandler(new TimerHandler(0.1f, true, new ITimerCallback() {
#Override
public void onTimePassed(final TimerHandler pTimerHandler) {
if (LittleManPos[0] == CurrentPosRow && LittleManPos[1] == CurrentPosColumn) {
if (!LittleMan.collidesWith(MapRectangles[CurrentPosRow][CurrentPosColumn])) {
RestartScene();
}
}
}
}));
}
It seems he can move to the block and sit there with it moving in and out beneath him but it doesn't call RestartScene() UNTIL I move him again. Any idea where I am going wrong? Or is there another way to do this?
Why don't create a Timer?
TimerTask task = new TimerTask(){
#Override
public void run(){
// your code goes here
}
};
Timer timer = new Timer();
timer.sechedule(task, 0, 100); // 100 --> 0.1 second
To cancel the Timer, call timer.cancel();.

How to display a Swing timer's remaining time in one second intervals?

I've been working on a simple game using a Java Applet in which the player's goal is to get as many points as possible within a 30 second timeframe. Right now, I'm using a Swing timer to count down from 30 seconds, and once the 0 mark is reached, a "game over" screen is displayed with the player's score. I have these instance variables:
ActionListener listener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
screenState = 0;
repaint();
}
};
Timer displayTimer = new Timer(30000, listener);
When the player clicks the "play" button, I execute displayTimer.start();.
Then, I have this within the appropriate case in my paint class:
g.drawString("Time Remaining: " + displayTimer.getDelay()/1000, 650, 100);
So, obviously, right now it's just displaying a static "Time Remaining: 30", and the screens switches after 30 seconds. What I'm trying to figure out is how I can repaint this value every one second so that it's a live timer. The only help I've been able to find thus far is for people use components.
ActionListener listener = new ActionListener() {
int count = 0;
#Override
public void actionPerformed(ActionEvent e) {
if (count++==30) {
screenState = 0;
}
repaint();
}
};
Timer displayTimer = new Timer(1000, listener); // make it 30 times faster
You can use the a Thread that sleep it every one second using the sleep method of it
Here is a little sample that count to 30 with 1 second interval
public static void main(String[] args) {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
int count = 0;
while(true)
{
if(count == 30) //end at 30 second
break;
try {
Thread.sleep(1000);
System.out.println("updated");
++count;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t.start();
}

How do I make this java for loop pause for 1/2 a second between each iteration?

private class MultipleGensListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
for(int i = 0; i < 25; i++)
{
game.runSimulationOneGen();
changeGrid();
}
}
}
//this is the loop. The changeGrid method displays a game grid on a GUI but
// only the 25th iteration is visible on screen. I would like each one to be
// visible for about a half a second before the loop continues.
// I have seen some questions answered on here that are very close to what I'm asking,
// but I just don't really understand how to apply it to my program..
// thanks for any help.
If the code performed by the simulation is quick and does not consume too much CPU and time, then consider using a Swing Timer to do your looping and delay. Otherwise, you'll need to use a background thread such as can be done with a SwingWorker object.
For e.g. if using both Swing Timer and SwingWorker:
private class MultipleGensListener implements ActionListener {
protected static final int MAX_INDEX = 25;
public void actionPerformed(ActionEvent e) {
int timerDelay = 500; // ms delay
new Timer(timerDelay, new ActionListener() {
int index = 0;
public void actionPerformed(ActionEvent e) {
if (index < MAX_INDEX) { // loop only MAX_INDEX times
index++;
// create the SwingWorker and execute it
new SwingWorker<Void, Void>() {
#Override
protected Void doInBackground() throws Exception {
game.runSimulationOneGen(); // this is done in background thread.
return null;
}
#Override
protected void done() {
changeGrid(); // this is called on EDT after background thread done.
}
}.execute(); // execute the SwingWorker
} else {
((Timer) e.getSource()).stop(); // stop the timer
}
}
}).start(); // start the Swing timer
}
}
NEVER BLOCK THE GUI EVENT THREAD
you can use a timer for that and have it only fire 25 times
final Timer t = new Timer(500,null);
t.addActionListener(new ActionListener(){
int i=0;
public void actionPerformed(ActionEvent e){
game.runSimulationOneGen();//run 1 iteration per tick
changeGrid();
if(i>25){t.stop();}
i++;
}
});
t.setRepeats(true);
t.start();
btw the reason only the last iteration is shown is that gui updates (redraws) are done in a separate event, but to let another event trigger you need to return from the listener method which you didn't
the Timer I showed is a more elaborate iteration which lets other events run in between iterations allowing the gui to show the changes
check my post that shows both methods java.swing.Timer#setDelay(int)
and
correct usage of Thread.sleep(int)
java wait cursor display problem

Categories

Resources