Android Quiz Game - Таймер обратного отсчета для каждого вопроса
Я создал приложение для викторины для Android, используя руководство здесь:http://automateddeveloper.blogspot.co.uk/2011/06/getting-started-complete-android-app.html
На каждый вопрос у пользователя будет только 20 секунд, чтобы ответить на него. Если он / она не отвечает в течение 20 секунд,AlertDialog
появится, и игра прекратится.
Для этого я добавил счетчик вOnCreate
методQuestionActivity class
:
final TextView myCounter = (TextView) findViewById(R.id.countdown);
new CountDownTimer(20000, 1000) {
@Override
public void onFinish() {
timeUp();
}
@Override
public void onTick(long millisUntilFinished) {
myCounter.setText("Time left: "
+ String.valueOf(millisUntilFinished / 1000));
}
}.start();
public void timeUp() {
AlertDialog.Builder builder = new AlertDialog.Builder(
QuestionActivity.this);
builder.setTitle("Times up!")
.setMessage("Game over")
.setCancelable(false)
.setNeutralButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
QuestionActivity.this.finish();
}
});
AlertDialog alert = builder.create();
alert.show();
}
Счетчик работает отображает и функционирует на экране правильно. После ответа на вопрос действие переходит к следующему вопросу, и счетчик снова сбрасывается до 20 секунд.
The problem
Тест состоит из 15 вопросов, после ответа на 3 или 4 вопроса приложение вылетает, и я получаю следующую ошибку:
07-18 00:49:05.530: E/AndroidRuntime(4867): android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@41533a80 is not valid; is your activity running?
Я считаю, что это относится кAlertDialog
, Я посмотрел этот код ошибки на Stackoverflow и популярное решение состоит в том, чтобы передатьActivityName.this
в качестве контекста при построенииAlertDialog
.
К сожалению, это не решает проблему.
Я считаю, что счетчик устанавливает ограничение времени 20 секунд для всей активности. Мое требование - 20 секунд на каждый вопрос.
Однако счетчик сбрасываетс до 20 секунд, когда пользователь нажимает & apos;Next
Кнопка и действие переходит к следующему вопросу.
Должен ли я сбросить счетчик, когда пользователь нажимаетNext
кнопка? ЗдесьOnClickListener
код дляNext
кнопка
if (currentGame.isGameOver()) {
Intent i = new Intent(this, EndgameActivity.class);
startActivity(i);
finish();
} else {
Intent i = new Intent(this, QuestionActivity.class);
startActivity(i);
SHOULD I ADD SOMETHING HERE?
finish();
Can anyone help me code a solution to my problem?
Вот весь код вQuestionActivity.class
public class QuestionActivity extends SherlockActivity implements
OnClickListener {
private Question currentQ;
private GamePlay currentGame;
private Context context;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.question);
getSupportActionBar().hide();
/**
* Configure current game and get question
*/
currentGame = ((ChuckApplication) getApplication()).getCurrentGame();
currentQ = currentGame.getNextQuestion();
Button nextBtn = (Button) findViewById(R.id.nextBtn);
nextBtn.setOnClickListener(this);
Button quitBtn = (Button) findViewById(R.id.quitBtn);
quitBtn.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
finish();
}
});
//Update the question and answer options..
setQuestions();
final TextView myCounter = (TextView) findViewById(R.id.countdown);
new CountDownTimer(20000, 1000) {
@Override
public void onFinish() {
// myCounter.setText("Time up!");
timeUp(context);
}
@Override
public void onTick(long millisUntilFinished) {
myCounter.setText("Time left: "
+ String.valueOf(millisUntilFinished / 1000));
}
}.start();
}
public void timeUp(Context context) {
AlertDialog.Builder builder = new AlertDialog.Builder(
QuestionActivity.this);
builder.setTitle("Times up!")
.setMessage("Game over")
.setCancelable(false)
.setNeutralButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
QuestionActivity.this.finish();
}
});
AlertDialog alert = builder.create();
alert.show();
}
/**
* Method to set the text for the question and answers from the current
* games current question
*/
private void setQuestions() {
// set the question text from current question
String question = Utility.capitalise(currentQ.getQuestion()) + "?";
TextView qText = (TextView) findViewById(R.id.question);
qText.setText(question);
// set the available options
List<String> answers = currentQ.getQuestionOptions();
TextView option1 = (TextView) findViewById(R.id.answer1);
option1.setText(Utility.capitalise(answers.get(0)));
TextView option2 = (TextView) findViewById(R.id.answer2);
option2.setText(Utility.capitalise(answers.get(1)));
TextView option3 = (TextView) findViewById(R.id.answer3);
option3.setText(Utility.capitalise(answers.get(2)));
TextView option4 = (TextView) findViewById(R.id.answer4);
option4.setText(Utility.capitalise(answers.get(3)));
}
public void onClick(View arg0) {
//validate a checkbox has been selected
if (!checkAnswer())
return;
//check if end of game
if (currentGame.isGameOver()) {
Intent i = new Intent(this, EndgameActivity.class);
startActivity(i);
finish();
} else {
Intent i = new Intent(this, QuestionActivity.class);
startActivity(i);
finish();
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
return true;
}
return super.onKeyDown(keyCode, event);
}
/**
* Check if a checkbox has been selected, and if it has then check if its
* correct and update gamescore
*/
private boolean checkAnswer() {
String answer = getSelectedAnswer();
if (answer == null) {
// Log.d("Questions", "No Checkbox selection made - returning");
return false;
} else {
// Log.d("Questions",
// "Valid Checkbox selection made - check if correct");
if (currentQ.getAnswer().equalsIgnoreCase(answer)) {
// Log.d("Questions", "Correct Answer!");
currentGame.incrementRightAnswers();
} else {
// Log.d("Questions", "Incorrect Answer!");
currentGame.incrementWrongAnswers();
}
return true;
}
}
private String getSelectedAnswer() {
RadioButton c1 = (RadioButton) findViewById(R.id.answer1);
RadioButton c2 = (RadioButton) findViewById(R.id.answer2);
RadioButton c3 = (RadioButton) findViewById(R.id.answer3);
RadioButton c4 = (RadioButton) findViewById(R.id.answer4);
if (c1.isChecked()) {
return c1.getText().toString();
}
if (c2.isChecked()) {
return c2.getText().toString();
}
if (c3.isChecked()) {
return c3.getText().toString();
}
if (c4.isChecked()) {
return c4.getText().toString();
}
return null;
}