Android Jeu de Quiz - compte à Rebours pour chaque qstion
J'ai créé un Quiz pour Android en utilisant le tutoriel ici: http://automateddeveloper.blogspot.co.uk/2011/06/getting-started-complete-android-app.html
Pour chaque question, l'utilisateur aura seulement 20 secondes pour y répondre. Si il/elle n'a pas de réponse dans les 20 secondes, un AlertDialog
popup et le jeu prendra fin.
Pour ce faire, j'ai ajouté un compteur dans le OnCreate
méthode de 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();
}
Le compteur fonctionne les affichages et les fonctions sur l'écran correctement. Après avoir répondu à une question, l'activité se déplace vers la question suivante, et le compteur se réinitialise à 20 secondes.
Le problème
Le quiz de 15 questions, après avoir répondu à 3 ou 4 questions, l'application se bloque et j'obtiens l'erreur suivante:
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?
Je crois que cela se rapporte à la AlertDialog
. J'ai regardé ce code d'erreur sur Stackoverflow et le populaire, la solution est de passer ActivityName.this
que le contexte lors de la construction de la AlertDialog
.
Malheureusement, cela ne résout pas le problème.
Je crois que le compteur est la fixation d'un délai de 20 secondes pour l'ensemble de l'activité. Mon exigence est de 20 secondes pour chaque question.
Toutefois, le compteur est remis à zéro à 20 secondes lorsque l'utilisateur appuyez sur la touche' Next
bouton et l'activité se déplace à la prochaine question.
Devrais-je être à la réinitialisation du compteur lorsque l'utilisateur appuie sur la Next
bouton? Voici la OnClickListener
code de la Next
bouton
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();
Quelqu'un peut-il m'aider à coder une solution à mon problème?
Voici tout le code dans 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;
}
Vous devez vous connecter pour publier un commentaire.
Je pense que l'activité n'existe plus à un certain point, lorsque vous essayez de faire de la boîte de dialogue(probablement lors de la
CountDownTimer
est proche de la fin?!?).De toute façon je pense que la finition et le départ de la même activité, pour chaque question, n'est-ce pas une bonne idée, au lieu de cela vous pouvez utiliser l'activité en cours et il suffit de redémarrer le chronomètre. Par exemple:
et dans le
onClick
de rappel à faire de même à l'installation d'une nouvelle question, arrêter le old timer et le redémarrage de la nouvelle minuterie:Aussi, dans la fonction de rappel pour la
Dialog
'sButton
je voudrais d'abord fermer laDialog
avant la fin de l'Activity
:if (currentGame.isGameOver()) { if (mCountDown != null) { mCountDown.cancel(); } ...
et voir si cela résout le problème.radioGroup.clearCheck()
au début desetQuestions()
méthode.