2012-07-18 3 views
2

을위한 카운트 다운 타이머 : 각 질문에 대한 http://automateddeveloper.blogspot.co.uk/2011/06/getting-started-complete-android-app.html안드로이드 퀴즈 게임 - 내가 여기 자습서를 사용하여 안드로이드에 대한 퀴즈 응용 프로그램을 만든 각 qstion

, 사용자는 답변을 20 초 만 할 것이다. 20 초 내에 응답하지 않으면 AlertDialog이 나타나고 게임이 종료됩니다. 이렇게하려면

, 나는 QuestionActivity classOnCreate 방법에 카운터를 추가 한 :

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 초로 재설정됩니다.

문제

퀴즈가 3 ~ 4 문제, 응용 프로그램 충돌 응답 후 15 개 질문을 가지고 있으며, 나는 다음과 같은 오류 얻을 :

07-18 00:49:05.530: E/AndroidRuntime(4867): android.view.WindowManager$BadTokenException: Unable to add window -- token [email protected] is not valid; is your activity running? 

나는 이것이 AlertDialog에 관한 생각을. Stackoverflow에서이 오류 코드를 찾아 보았고 대중적인 솔루션은 AlertDialog을 작성할 때 ActivityName.this을 컨텍스트로 전달하는 것입니다.

불행히도이 방법으로는 문제가 해결되지 않습니다.

저는 카운터가 전체 활동 시간 제한을 20 초로 설정하고 있다고 생각합니다. 내 질문은 각 질문마다 20 초입니다.

그러나 사용자가 'Next'버튼을 누르면 카운터가 20 초로 재설정되고 활동이 다음 질문으로 이동합니다.

사용자가 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(); 

이 사람이 내 문제에 대한 해결책을 코드 도움을 줄 수 Next 버튼의 OnClickListener 코드는? 여기

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

답변

6

QuestionActivity.class의 모든 코드가 난 당신이 CountDownTimer가 거의 다 아마 때 (대화 상자를 만들려고 할 때 활동이 특정 지점에서 더 이상 존재하지 않을 생각입니다! ?).

어쨌든 나는 각 질문에 대해 동일한 활동을 마치고 시작하는 것이 그리 좋은 생각이 아니라고 생각합니다. 대신 현재 활동을 사용하고 단순히 타이머를 다시 시작할 수 있습니다.예를 들어 :

public class QuestionActivity extends SherlockActivity implements 
    OnClickListener { 

    private CountDownTimer mCountDown; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     // ... 
     mCountDown = 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(); 
     // ... 

onClick 콜백에서

이 설정에 새로운 질문을 동일한 작업을 수행, 기존의 타이머를 중지하고 새로운 타이머 다시 시작하십시오 Dialog '에 대한 콜백에서, 또한

//check if end of game 
if (currentGame.isGameOver()) { 
    Intent i = new Intent(this, EndgameActivity.class); 
    startActivity(i); 
    finish(); 
} else { 
    if (mCountDown != null) { 
     mCountDown.cancel(); 
    } 
    currentQ = currentGame.getNextQuestion(); 
    setQuestions(); 
    mCountDown = 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(); 
} 

을 의 Button 내가 먼저 Activity을 마무리하기 전에 Dialog을 닫을 것 :

((AlertDialog) dialog).dismiss(); 
QuestionActivity.this.finish(); 
+0

감사의 친구를. 나는 오늘 밤 집에 올 때 이것을 시도 할 것이다. – tiptopjat

+0

모든 코드를 추가 했으므로 카운터 문제가 해결되었습니다. 그러나 퀴즈가 끝나고 EndgameActivity.class를 시작하면 20 초 후에 WindowManager $ BadTokenException 오류가 발생합니다. 타이머가 아직 실행 중이며 AlertDialog를 표시하려고합니다. EndgameActivity 활동을 시작한 후 finish()를 사용하고 있습니다. 내가 뭘 잘못하고 있는거야? – tiptopjat

+1

@tiptopjat 게임이 끝났을 때 타이머를 멈추는 코드를 다음과 같이 추가하십시오 :'if (currentGame.isGameOver()) {if (mCountDown! = null) { mCountDown.cancel(); } ... '문제가 해결되는지 확인하십시오. – Luksprog