【问题标题】:How to exit an infinite while loop when user taps screen?用户点击屏幕时如何退出无限循环?
【发布时间】:2014-01-28 18:06:27
【问题描述】:

我目前有一个当用户点击屏幕时启动的 while 循环。循环是无限的,当它感应到用户再次点击屏幕时应该停止。 (而且,如果再次点击,它将再次开始循环,等等。)我尝试以两种不同的方式打破循环,但都产生了不令人满意的结果:

方法 1: 当我尝试这种方法时,发生的情况是用户点击,循环开始。用户再次点击,并且该点击没有被注册,并且循环继续进行。

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;
}

方法2:当我尝试这种方法时,发生的情况是用户点击,循环开始,经过一次迭代,然后停止。

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;
}

我已经查看了这些问题,但对于我的具体情况都没有帮助:

那么我该如何实现这个while循环呢?我只想要一个简单的界面,用户点击它会打开/关闭 while 循环。

【问题讨论】:

  • 关键问题是你在 UI 线程上运行你的无限循环,因此它被阻止接收更多的触摸事件。

标签: java android while-loop


【解决方案1】:

将无限循环放在Thread 中。有了它,你可以在里面有一个控制变量(比如playing),然后再次点击,你想停止,只需将其设置为false。并行运行的Thread 将能够处理这两个事件(点击和线程停止)。

---- 编辑----

添加示例:

// 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;
}

【讨论】:

  • 谢谢。这听起来很有希望,但我不知道该怎么写。你有例子吗?
  • 我加了一个例子,检查一下。
  • 我已经按照上面的说明复制了您的示例,但 IDE(在本例中为 Eclipse)一直告诉我 Runnable() 区域周围存在语法错误。我试过添加/删除括号和方括号,但总是有问题;我不确定为什么。你知道我可能会错过什么吗?
  • 糟糕,我离开了run() 方法!我编辑了我的答案,请现在检查。
【解决方案2】:

试试这个:

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;
    }
});

【讨论】:

  • 我看到了runner.run()',但是有没有类似runner.stop()(或类似的)来暂停Runnable?另外,我应该将我的 while 循环移到 run() 方法内吗?
猜你喜欢
  • 1970-01-01
  • 2016-11-07
  • 2020-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-20
  • 1970-01-01
相关资源
最近更新 更多