如何在 Android Studio 中正确使用 postDelayed()?

新手上路,请多包涵

我有一个 countDownTimer,如果用户在第 12 秒内没有点击 gameButton,我希望调用 gameOver 方法。

问题是,当 countDownTimer 为 12 时,游戏函数会立即被调用,或者计时器只是不断倒计时。

所以我试图使用 postDelayed() 方法给用户一整秒的时间来点击按钮并让 countDownTimer 继续,但是因为我的代码现在游戏在 12 停止。

 import android.app.Activity;
import android.os.CountDownTimer;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class GameScreen extends Activity {
    private TextView time;
    private Button start;
    private Button cancel;
    private Button gameButton;
    private CountDownTimer countDownTimer;
    public static int count = 0;
    public static int countFail = 0;

    final Handler handler = new Handler();
    final Runnable r = new Runnable() {
        public void run() {
            handler.postDelayed(this, 1000);
            gameOver();
        }
    };

    private View.OnClickListener btnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            switch(v.getId()){
                case R.id.start_ID :
                    start();
                    break;
                case R.id.cancel :
                    cancel();
                    break;
                case R.id.gameButton_ID :
                    gameButton();
                    break;
            }
        }
    };

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

        start = (Button) findViewById(R.id.start_ID);
        start.setOnClickListener(btnClickListener);
        cancel = (Button) findViewById(R.id.cancel);
        cancel.setOnClickListener(btnClickListener);
        time = (TextView) findViewById(R.id.time);
        gameButton = (Button) findViewById(R.id.gameButton_ID);
        gameButton.setOnClickListener(btnClickListener);
    }

    public void start() {
        time.setText("16");
        //This doesn't work and makes app crash when you hit start button
        countDownTimer = new CountDownTimer(16 * 1000, 1000) {
            @Override
            public void onTick(long millsUntilFinished) {
                time.setText("" + millsUntilFinished / 1000);

                //turns textview string to int
                int foo = Integer.parseInt(time.getText().toString());

                if (time.getText().equals("12")) {
                    r.run();
                }
            }

            public void onFinish() {
                time.setText("Done !");
            }
        };
        countDownTimer.start();
    }

    private void cancel() {
        if(countDownTimer != null){
            countDownTimer.cancel();
            countDownTimer = null;
        }
    }

    private void gameOver() {
        Toast.makeText(getApplicationContext(), "You scored " + count, Toast.LENGTH_SHORT).show();
        count = 0;
        countFail = 0;
        cancel();
    }

    private void gameButton() {
        int foo = Integer.parseInt(time.getText().toString());

        if(foo  % 2 == 0 ) {
            Toast.makeText(getApplicationContext(), "PASS", Toast.LENGTH_SHORT).show();
            handler.removeCallbacks(r);
            ++count;
        }
        else {
            gameOver();
        }
    }
}

原文由 Ryder Thacker 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 524
1 个回答

您几乎正确地使用了 postDelayed(Runnable, long) ,但并不完全正确。让我们看看你的 Runnable。

 final Runnable r = new Runnable() {
    public void run() {
        handler.postDelayed(this, 1000);
        gameOver();
    }
};

当我们调用 r.run(); 它要做的第一件事就是告诉你的 handler 在 1000 毫秒后运行相同的 Runnable,然后调用 gameOver() 这实际上会导致您的 gameOver() 方法被调用两次:一次是立即调用,第二次是在 Handler 完成等待 1000 毫秒后调用。

相反,您应该将 Runnable 更改为:

 final Runnable r = new Runnable() {
    public void run() {
        gameOver();
    }
};

并这样称呼它:

 handler.postDelayed(r, 1000);

希望这可以帮助。

原文由 DanielLaneDC 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题