Search code examples
androidandroid-activity

Firing an event as soon as activity is visible to the user


I wanted to create countdown as soon as the user sees an activity. However, there does not seem to be an appropriate callback for that. Neither onResume nor onWindowFocusChanged seem to be the correct callbacks, because the whole code is executed before the user even see anything. As a result I end up with "Go!" on the screen right from the start.

In a nutshell: Do you have any idea how to implement a countdown without any user interaction as soon as the activity is visible to the user?

EDIT:

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.util.concurrent.TimeUnit;
import android.widget.TextView;

public class ChallengeModeTutorial extends AppCompatActivity {

    private void delayOneSec()
    {
        try
        {
            TimeUnit.SECONDS.sleep(2);
        }
        catch (InterruptedException e)
        {
            assert true;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_challenge_mode_tutorial);
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus)
    {
        super.onWindowFocusChanged(hasFocus);
        TextView readySteadyGo = (TextView) findViewById(R.id.challengeModeTutorialReadySteadyGoTextView);
        // TextView tutorialText = (TextView) findViewById(R.id.challengeModeTutorialTextTextView);
        TextView timeUntilStart = (TextView) findViewById(R.id.challengeModeTutorialReadyTimeTextView);

        readySteadyGo.setText("");
        timeUntilStart.setText("5");
        delayOneSec();
        timeUntilStart.setText("4");
        delayOneSec();
        timeUntilStart.setText("3");
        delayOneSec();
        readySteadyGo.setText("Ready!");
        timeUntilStart.setText("2");
        delayOneSec();
        readySteadyGo.setText("Steady!");
        timeUntilStart.setText("1");
        delayOneSec();
        readySteadyGo.setText("");
        readySteadyGo.setText("Go!");
    }
}

Solution

  • I finally got it to work like this:

    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.widget.TextView;
    
    public class ChallengeModeTutorial extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_challenge_mode_tutorial);
        }
    
        @Override
        protected void onStart()
        {
            super.onStart();
    
            final TextView readySteadyGo = (TextView) findViewById(R.id.challengeModeTutorialReadySteadyGoTextView);
            final TextView timeUntilStart = (TextView) findViewById(R.id.challengeModeTutorialReadyTimeTextView);
    
            readySteadyGo.setText("");
    
            Thread t=new Thread(){
    
                @Override
                public void run(){
    
                    while(continueThread){
    
                        try {
                            Thread.sleep(1000);
    
                            runOnUiThread(new Runnable() {
    
                                @Override
                                public void run() {
                                    if(currentCount > 0)
                                    {
                                        timeUntilStart.setText(String.valueOf(currentCount));
                                    }
                                    else
                                    {
                                        timeUntilStart.setText("Go!");
                                    }
                                    switch (currentCount)
                                    {
                                        case 2: readySteadyGo.setText("Ready!"); break;
                                        case 1: readySteadyGo.setText("Steady!"); break;
                                        default: readySteadyGo.setText(""); break;
                                    }
                                    currentCount--;
                                    if (currentCount == 0)
                                    {
                                        continueThread = false;
                                    }
                                }
                            });
    
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
    
                    }
                }
            };
    
            t.start();
        }
    
        private boolean continueThread = true;
        private int currentCount = 5;
    }