简体   繁体   中英

How to exit an infinite while loop when user taps screen?

I currently have a while loop that starts when a user taps the screen. The loop is meant to be infinite, and should stop when it senses another screen tap from the user. (And, if tapped again, it'll start looping again, etc.) I've tried to break the loop in two different ways, with both yielding non-satisfactory results:

METHOD 1: When I try this method, what happens is that the user taps, the loop starts. The user taps again, and that tap doesn't get registered and the loop just keeps on going.

boolean playing = false;
@Override
public boolean onTouch(View v, MotionEvent event) 
{
    if(event.getAction() == MotionEvent.ACTION_DOWN) 
    {
        if(!playing)
        {
            playing = true;
            while(playing)
            {
                //do something here
            }
        }
        else if(playing)
        {
            playing = false;
        }
    }
    return false;
}

METHOD 2: When I try this method, what happens is that the user taps, the loop starts, goes through one iteration, then stops.

boolean playing = false;
@Override
public boolean onTouch(View v, MotionEvent event) 
{
    if(event.getAction() == MotionEvent.ACTION_DOWN) 
    {
        if(!playing)
        {
            playing = true;         
            whileLoop:
            while(playing)
            {
                //do something here
            }
        }

        if(event.getAction() == MotionEvent.ACTION_DOWN) 
        {
            playing = false;
            break whileLoop;
        }
    }
    return false;
}

I've looked at these questions, but neither helped me with my specific situation:

So how do I implement this while loop? I just want a simple interface where a user's tap would toggle the while loop on/off.

Put the infinite loop within a Thread . Having it there, you can just have a control variable inside (like playing ), and once tap again and you want to stop, simply set it to false. The Thread , running paralelly, will be able to handle both events (the tap and the Thread stop).

---- EDIT ----

Example added:

// You'd probably need to store this variable class-wide,
// so you can control when the user has tapped for the first or second time
boolean playing = false;

@Override
public boolean onTouch(View v, MotionEvent event) 
{
    if(event.getAction() == MotionEvent.ACTION_DOWN) 
    {
        if(!playing)
        {
            playing = true;
            new Thread(
              new Runnable() {
                public void run() {
                  while(playing)
                  {
                    //do something here
                  }
                }
              }
            ).start();
        }
        else if(playing)
        {
            playing = false;
            // As you're controlling the playing value in the Thread,
            // setting it here to false would mean that your thread stops too.
        }
    }
    return false;
}

try this:

boolean playing = false;
Handler handler = new Handler();
Runnable runner = new Runnable() {
    @Override
    public void run() {
        // do something here
        handler.post(this);
    }
};

imageView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if(event.getAction() == MotionEvent.ACTION_DOWN)  {
            if(!playing) {
                playing = true;
                runner.run();
                return true;
            }
            if(playing) {
                playing = false;
                handler.removeCallbacks(runner);
                handler = null;
                runner = null;
                Toast.makeText(context, "NO", Toast.LENGTH_SHORT).show();
                return true;
            }
        }
        return false;
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM