I have created a Quiz app for Android using the tutorial here: http://automateddeveloper.blogspot.co.uk/2011/06/getting-started-complete-android-app.html
For each question, the user will only have 20 seconds to answer it. If he/she fails to answer in 20 seconds, an AlertDialog will popup and the game will terminate.
To do this, I have added a counter in the OnCreate method of 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();
}
The counter works displays and functions on screen correctly. After answering a question, the activity moves to the next question and the counter resets itself to 20 seconds again.
The problem
The quiz has 15 questions, after answering 3 or 4 questions, the app crashes and I get the following error:
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?
I believe this relates to the AlertDialog. I have looked up this error code on Stackoverflow and the popular solution is to pass ActivityName.this as the context when building the AlertDialog.
Unfortunately this does not solve the problem.
I believe the counter is setting a time limit of 20 seconds for the whole activity. My requirement is 20 seconds for each question.
However, the counter resets to 20 seconds when the user press the' Next button and the activity moves to the next question.
Should I be resetting the counter when the user presses the Next button? Here is the OnClickListener code for the Next button
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?
Here is all the code in 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;
}
I think the activity doesn't exist anymore at a certain point when you try to make the dialog(probably when the CountDownTimer is near the end?!?).
Anyway I think finishing and starting the same activity for each question isn't such a good idea, instead you could use the current activity and simply restart the timer. For example:
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();
// ...
and in the onClick callback do the same to setup a new question, stop the old timer and restart the new timer:
//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();
}
Also, in the callback for the Dialog's Button I would first close the Dialog before finishing the Activity:
((AlertDialog) dialog).dismiss();
QuestionActivity.this.finish();
Related
So when the last question is asked on the quiz, it doesn't show the dialog box if it is correct or not. And by the results screen the last question is always considered as 'correct'
public class MainGameActivity extends AppCompatActivity {
FButton buttonA, buttonB, buttonC, buttonD;
Button pause;
TextView questionText, triviaQuizText, timeText, resultText, coinText;
TriviaQuizHelper triviaQuizHelper;
TriviaQuestion currentQuestion;
MediaPlayer mysong;
List<TriviaQuestion> list;
int qid = 0;
int timeValue = 20;
int coinValue = 0;
CountDownTimer countDownTimer;
Typeface tb, sb;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game_main);
mysong = MediaPlayer.create(MainGameActivity.this,R.raw.hs);
mysong.start();
int media_length;
//Initializing variables
questionText = (TextView) findViewById(R.id.triviaQuestion);
pause = (Button) findViewById(R.id.pause);
buttonA = (FButton) findViewById(R.id.buttonA);
buttonB = (FButton) findViewById(R.id.buttonB);
buttonC = (FButton) findViewById(R.id.buttonC);
buttonD = (FButton) findViewById(R.id.buttonD);
triviaQuizText = (TextView) findViewById(R.id.triviaQuizText);
timeText = (TextView) findViewById(R.id.timeText);
resultText = (TextView) findViewById(R.id.resultText);
coinText = (TextView) findViewById(R.id.coinText);
pause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
pausedialog();
}
});
//Setting typefaces for textview and buttons - this will give stylish fonts on textview and button etc
tb = Typeface.createFromAsset(getAssets(), "fonts/TitilliumWeb-Bold.ttf");
sb = Typeface.createFromAsset(getAssets(), "fonts/shablagooital.ttf");
triviaQuizText.setTypeface(sb);
questionText.setTypeface(tb);
buttonA.setTypeface(tb);
buttonB.setTypeface(tb);
buttonC.setTypeface(tb);
buttonD.setTypeface(tb);
timeText.setTypeface(tb);
resultText.setTypeface(sb);
coinText.setTypeface(tb);
//Our database helper class
triviaQuizHelper = new TriviaQuizHelper(this);
//Make db writable
triviaQuizHelper.getWritableDatabase();
//It will check if the ques,options are already added in table or not
//If they are not added then the getAllOfTheQuestions() will return a list of size zero
if (triviaQuizHelper.getAllOfTheQuestions().size() == 0) {
//If not added then add the ques,options in table
triviaQuizHelper.allQuestion();
}
//This will return us a list of data type TriviaQuestion
list = triviaQuizHelper.getAllOfTheQuestions();
//Now we gonna shuffle the elements of the list so that we will get questions randomly
Collections.shuffle(list);
//currentQuestion will hold the que, 4 option and ans for particular id
currentQuestion = list.get(qid);
//countDownTimer
countDownTimer = new CountDownTimer(22000, 1000) {
public void onTick(long millisUntilFinished) {
//here you can have your logic to set text to timeText
timeText.setText(String.valueOf(timeValue) + "\"");
//With each iteration decrement the time by 1 sec
timeValue -= 1;
//This means the user is out of time so onFinished will called after this iteration
if (timeValue == -1) {
//Since user is out of time setText as time up
// resultText.setText(getString(R.string.timeup));
timeUp();
//Since user is out of time he won't be able to click any buttons
//therefore we will disable all four options buttons using this method
// disableButton();
}
}
//Now user is out of time
public void onFinish() {
//We will navigate him to the time up activity using below method
//timeUp();
}
}.start();
//This method will set the que and four options
updateQueAndOptions();
}
public void updateQueAndOptions() {
//This method will setText for que and options
questionText.setText(currentQuestion.getQuestion());
buttonA.setText(currentQuestion.getOptA());
buttonB.setText(currentQuestion.getOptB());
buttonC.setText(currentQuestion.getOptC());
buttonD.setText(currentQuestion.getOptD());
timeValue = 20;
//Now since the user has ans correct just reset timer back for another que- by cancel and start
countDownTimer.cancel();
countDownTimer.start();
//set the value of coin text
coinText.setText(String.valueOf(coinValue));
//Now since user has ans correct increment the coinvalue
coinValue++;
}
public void buttonA(View view) {
Button button = (Button) view;
buttonPressed(button);
}
public void buttonB(View view) {
Button button = (Button) view;
buttonPressed(button);
}
public void buttonC(View view) {
Button button = (Button) view;
buttonPressed(button);
}
public void buttonD(View view) {
Button button = (Button) view;
buttonPressed(button);
}
public void buttonPressed(Button button) {
if (qid < list.size() - 1) {
disableButton();
if (button.getText().equals(currentQuestion.getAnswer())) {
correctDialog();
} else {
incorrectDialog();
coinValue--;
}
} else {
gameWon();
}
}
//This method will navigate from current activity to GameWon
public void gameWon() {
Intent intent = new Intent(this, GameWon.class);
intent.putExtra("score", coinValue);
startActivity(intent);
finish();
}
//This method is called when user ans is wrong
//this method will navigate user to the activity PlayAgain
public void gameLostPlayAgain() {
Intent intent = new Intent(this, PlayAgain.class);
startActivity(intent);
finish();
}
//This method is called when time is up
//this method will navigate user to the activity Time_Up
public void timeUp() {
Intent intent = new Intent(this, Time_Up.class);
startActivity(intent);
finish();
}
//If user press home button and come in the game from memory then this
//method will continue the timer from the previous time it left
#Override
protected void onRestart() {
super.onRestart();
mysong.getCurrentPosition();
mysong.start();
countDownTimer.start();
}
//When activity is destroyed then this will cancel the timer
#Override
protected void onStop() {
super.onStop();
countDownTimer.cancel();
}
//This will pause the time/
#Override
protected void onPause() {
super.onPause();
mysong.pause();
countDownTimer.cancel();
}
//On BackPressed
#Override
public void onBackPressed() {
Intent intent = new Intent(this, HomeScreen.class);
startActivity(intent);
finish();
}
//This dialog is show to the user after he ans correct
public void correctDialog() {
final Dialog dialogCorrect = new Dialog(MainGameActivity.this);
dialogCorrect.requestWindowFeature(Window.FEATURE_NO_TITLE);
if (dialogCorrect.getWindow() != null) {
ColorDrawable colorDrawable = new ColorDrawable(Color.TRANSPARENT);
dialogCorrect.getWindow().setBackgroundDrawable(colorDrawable);
}
dialogCorrect.setContentView(R.layout.dialog_correct);
dialogCorrect.setCancelable(false);
dialogCorrect.show();
//Since the dialog is show to user just pause the timer in background
onPause();
onRestart();
TextView correctText = (TextView) dialogCorrect.findViewById(R.id.correctText);
FButton buttonNext = (FButton) dialogCorrect.findViewById(R.id.dialogNext);
//Setting type faces
correctText.setTypeface(sb);
buttonNext.setTypeface(sb);
//OnCLick listener to go next que
buttonNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//This will dismiss the dialog
dialogCorrect.dismiss();
//it will increment the question number
qid++;
//get the que and 4 option and store in the currentQuestion
currentQuestion = list.get(qid);
//Now this method will set the new que and 4 options
updateQueAndOptions();
//reset the color of buttons back to white
resetColor();
//Enable button - remember we had disable them when user ans was correct in there particular button methods
enableButton();
}
});
}
//INCORRECT//////////////////////////////////////////////////////////////
public void incorrectDialog() {
final Dialog incorrectDialog = new Dialog(MainGameActivity.this);
incorrectDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
if (incorrectDialog.getWindow() != null) {
ColorDrawable colorDrawable = new ColorDrawable(Color.TRANSPARENT);
incorrectDialog.getWindow().setBackgroundDrawable(colorDrawable);
}
incorrectDialog.setContentView(R.layout.dialog_incorrect);
incorrectDialog.setCancelable(false);
incorrectDialog.show();
//Since the dialog is show to user just pause the timer in background
onPause();
onRestart();
TextView IncorrectText = (TextView) incorrectDialog.findViewById(R.id.IncorrectText);
FButton buttonNext = (FButton) incorrectDialog.findViewById(R.id.dialogNext);
//Setting type faces
IncorrectText.setTypeface(sb);
buttonNext.setTypeface(sb);
//OnCLick listener to go next que
buttonNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//This will dismiss the dialog
incorrectDialog.dismiss();
//it will increment the question number
qid++;
//get the que and 4 option and store in the currentQuestion
currentQuestion = list.get(qid);
//Now this method will set the new que and 4 options
updateQueAndOptions();
//reset the color of buttons back to white
resetColor();
//Enable button - remember we had disable them when user ans was correct in there particular button methods
enableButton();
}
});
}
//This method will make button color white again since our one button color was turned green
public void resetColor() {
buttonA.setButtonColor(ContextCompat.getColor(getApplicationContext(),R.color.white));
buttonB.setButtonColor(ContextCompat.getColor(getApplicationContext(),R.color.white));
buttonC.setButtonColor(ContextCompat.getColor(getApplicationContext(),R.color.white));
buttonD.setButtonColor(ContextCompat.getColor(getApplicationContext(),R.color.white));
}
//This method will disable all the option button
public void disableButton() {
buttonA.setEnabled(false);
buttonB.setEnabled(false);
buttonC.setEnabled(false);
buttonD.setEnabled(false);
}
//This method will all enable the option buttons
public void enableButton() {
buttonA.setEnabled(true);
buttonB.setEnabled(true);
buttonC.setEnabled(true);
buttonD.setEnabled(true);
}
public void pausedialog()
{
final Dialog pausedialog = new Dialog(MainGameActivity.this);
pausedialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
if (pausedialog.getWindow() != null) {
ColorDrawable colorDrawable = new ColorDrawable(Color.TRANSPARENT);
pausedialog.getWindow().setBackgroundDrawable(colorDrawable);
}
pausedialog.setContentView(R.layout.activity_dialog_pause);
pausedialog.setCancelable(false);
pausedialog.show();
//Since the dialog is show to user just pause the timer in background
onPause();
Button resume = (FButton) pausedialog.findViewById(R.id.resume);
Button menu = (FButton) pausedialog.findViewById(R.id.menu);
Button music = (FButton) pausedialog.findViewById(R.id.music);
resume.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//This will dismiss the dialog
pausedialog.dismiss();
onRestart();
}
});
menu.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent2 = new Intent(MainGameActivity.this,HomeScreen.class);
// mysong.release();
// finish();
startActivity(intent2);
finish();
}
});
}
}
EDIT: posted the full code. I tried understanding it again but I don't know what to do anymore this may be the only problem I have left other than inserting images (that's another problem for now I wanna finish this)
EDIT: I tried fixing the if statements like this:
if (button.getText().equals(currentQuestion.getAnswer())) {
correctDialog();
} else {
incorrectDialog();
coinValue--;
}
if (qid < list.size() - 1) {
disableButton();
} else
{
gameWon();
}
It works now, the last answer is now also registered if right or wrong BUT the dialog box flashes for a split second and automatically goes to the results screen.
I am making a quiz app when I pressing the answer it was not showing the next question directly it was going to done activity where the score of the quiz will be displayed. Please tell me what to do and the changes i have to made for it. Please tell me in detail and which line the problem causes, because I am still learning, plz And also suggest me some improvements.
public class Playing extends AppCompatActivity implements View.OnClickListener {
final static long INTERVAL = 1000; // 1sec = 1000
final static long TIMEOUT = 7000; // 7000 = 7sec
int progressValue = 0;
CountDownTimer mCountDown;
int index = 0, score = 0, thisQuestion = 0, totalQuestion, correctAnswer;
ProgressBar progressBar;
ImageView question_image;
Button btnA, btnB, btnC, btnD;
TextView txtScore, txtQuestionNum, question_text;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_playing);
//View
txtScore = (TextView) findViewById(R.id.txtScore);
txtQuestionNum = (TextView) findViewById(R.id.txtTotalQuestion);
question_text = (TextView) findViewById(R.id.question_text);
question_image = (ImageView) findViewById(R.id.question_image);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
btnA = (Button) findViewById(R.id.btnAnswerA);
btnB = (Button) findViewById(R.id.btnAnswerB);
btnC = (Button) findViewById(R.id.btnAnswerC);
btnD = (Button) findViewById(R.id.btnAnswerD);
btnA.setOnClickListener(this);
btnB.setOnClickListener(this);
btnC.setOnClickListener(this);
btnD.setOnClickListener(this);
}
#Override
public void onClick(View view) {
mCountDown.cancel();
if (index < totalQuestion) //still have question in List
{
Button clickedButton = (Button) view;
if (clickedButton.getText().equals(Common.questionList.get(index).getCorrectAnswer())) {
//Choose correct answer
score += 10;
correctAnswer++;
showQuestion(++index); //next question
} else {
//Choose wrong answer
Intent intent = new Intent(this, Done.class);
Bundle dataSend = new Bundle();
dataSend.putInt("SCORE", score);
dataSend.putInt("TOTAL", totalQuestion);
dataSend.putInt("CORRECT", correctAnswer);
intent.putExtras(dataSend);
startActivity(intent);
finish();
}
}
}
private void showQuestion(int index) {
if (index < totalQuestion) {
thisQuestion++;
txtQuestionNum.setText(String.format(Locale.getDefault(), "%d / %d", thisQuestion, totalQuestion));
progressBar.setProgress(0);
progressValue = 0;
if (Common.questionList.get(index).getIsImageQuestion().equals("true")) {
//if is image
Picasso.get().load(Common.questionList.get(index).getQuestion()).into(question_image);
question_image.setVisibility(View.VISIBLE);
question_text.setVisibility(View.INVISIBLE);
} else {
question_text.setText(Common.questionList.get(index).getQuestion());
//If question is text,we will set image to invisible
question_image.setVisibility(View.INVISIBLE);
question_text.setVisibility(View.VISIBLE);
}
btnA.setText(Common.questionList.get(index).getAnswerA());
btnB.setText(Common.questionList.get(index).getAnswerB());
btnC.setText(Common.questionList.get(index).getAnswerC());
btnD.setText(Common.questionList.get(index).getAnswerD());
mCountDown.start(); //Start timer
} else {
//If it is final question
Intent intent = new Intent(this, Done.class);
Bundle dataSend = new Bundle();
dataSend.putInt("SCORE", score);
dataSend.putInt("TOTAL", totalQuestion);
dataSend.putInt("CORRECT", correctAnswer);
intent.putExtras(dataSend);
startActivity(intent);
finish();
}
}
#Override
protected void onResume() {
super.onResume();
totalQuestion = Common.questionList.size();
mCountDown = new CountDownTimer(TIMEOUT, INTERVAL) {
#Override
public void onTick(long minisec) {
progressBar.setProgress(progressValue);
progressValue++;
}
#Override
public void onFinish() {
mCountDown.cancel();
showQuestion(++index);
}
};
showQuestion(index);
}
}
There is no onClickListener within your Activity. I would recommend creating a "next()" function, and then, for each of the buttons, do something along the lines of:
btn.setOnClickListener(new View.OnClickListener(){
next()
})
I create a simple math game and I would like to update my progress bar base on the right question answer.
Examples: every time I answer correctly to a question the progress bar should go bu 10% and so on.
public class QuestionActivity extends Activity
{
List<Question> quesList;
int score = 0;
int qid = 0;
Question currentQ;
TextView txtQuestion, times, scored;
Button button1, button2, button3;
ProgressBar pb;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
QuizHelper db = new QuizHelper(this); // my question bank class
quesList = db.getAllQuestions(); // this will fetch all quetonall
questions
currentQ = quesList.get(qid); // the current question
// the textview in which the question will be displayed
txtQuestion = (TextView) findViewById(R.id.txtQuestion);
//the progress bar in which progress will be displayed
pb = (ProgressBar)findViewById(R.id.progressBar);
// the three buttons,
// the idea is to set the text of three buttons with the options from
question bank
button1 = (Button) findViewById(R.id.button1);
button2 = (Button) findViewById(R.id.button2);
button3 = (Button) findViewById(R.id.button3);
// the textview in which score will be displayed
scored = (TextView) findViewById(R.id.score);
// the timer
times = (TextView) findViewById(R.id.timers);
// method which will set the things up for our game
setQuestionView();
times.setText("00:02:00");
// A timer of 60 seconds to play for, with an interval of 1 second (1000
milliseconds)
CounterClass timer = new CounterClass(60000, 1000);
timer.start();
// button click listeners
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// passing the button text to other method
// to check whether the answer is correct or not
// same for all three buttons
getAnswer(button1.getText().toString());
setProgressBar();
}
});
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getAnswer(button2.getText().toString());
setProgressBar();
}
});
button3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getAnswer(button3.getText().toString());
setProgressBar();
}
});
}
public void getAnswer(String AnswerString) {
if (currentQ.getAnswer().equals(AnswerString)) {
// if conditions matches increase the int (score) by 1
// and set the text of the score view
score++;
scored.setText("Score : " + score);
} else {
// if unlucky start activity and finish the game
Intent intent = new Intent(QuestionActivity.this,
ResultActivity.class);
// passing the int value
Bundle b = new Bundle();
b.putInt("score", score); // Your score
intent.putExtras(b); // Put your score to your next
startActivity(intent);
finish();
}
if (qid < 20) {
// if questions are not over then do this
currentQ = quesList.get(qid);
setQuestionView();
} else {
// if over do this
Intent intent = new Intent(QuestionActivity.this,
ResultActivity.class);
Bundle b = new Bundle();
b.putInt("score", score); // Your score
intent.putExtras(b); // Put your score to your next
startActivity(intent);
finish();
}
}
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
#SuppressLint("NewApi")
public class CounterClass extends CountDownTimer {
public CounterClass(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
// TODO Auto-generated constructor stub
}
#Override
public void onFinish() {
times.setText("Time is up");
}
//#Override
public void onTick(long millisUntilFinished) {
// TODO Auto-generated method stub
long millis = millisUntilFinished;
String hms = String.format(
"%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis)
- TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS
.toHours(millis)),
TimeUnit.MILLISECONDS.toSeconds(millis)
- TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS
.toMinutes(millis)));
System.out.println(hms);
times.setText(hms);
}
}
private void setQuestionView() {
// the method which will put all things together
txtQuestion.setText(currentQ.getQuestion());
button1.setText(currentQ.getOptionA());
button2.setText(currentQ.getOptionB());
button3.setText(currentQ.getOptionC());
qid++;
}
private void setProgressBar()
{
}
}
private void setProgressBar()
{
int progress=pb.getProgress();
if(progress<100)
pb.setProgress(progress+10)
}
this should do the trick, it will increase progress by 10 every time you call setProgressBar() method
First :
Set ur Progress bar limit
pb.setMax(Total Quest *10)
later in
For every Correct Answer Inc score++;
private void setProgressBar()
{
pb.setProgress(score*10);
}
I'm working on a quiz app that has a question and to answer options. When the wrong answer (button) is clicked, the text color for that specific button turns red, as it should. However, when the right button is clicked, the text color for that particular button should turn green, wait a second, and then move on to the next question.
I have spent days trying to figure out why it doesn't work, googled for answers, but I still can't make it work.
I have tried using Handlers and Runnables, but it still doesn't work.
I have posted the full code for the activity below.
Please help!
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.question_layout);
Intent i = getIntent();
subject = (Subject) i.getSerializableExtra(Globals.SUBJECT);
questions = subject.getQuestions();
subjectId = subject.getSubjectId();
appPreferences = new AppPreferences();
livesLeft = 3;
index = 0;
maxQuestions = questions.size();
maxIndex = maxQuestions - 1;
progressBar = (ProgressBar) findViewById(R.id.progressBar);
progressBar.setMax(maxQuestions);
answer1 = (Button) findViewById(R.id.buttonAnswer1);
answer2 = (Button) findViewById(R.id.buttonAnswer2);
setQuestionsAndAnswers(index);
TextView textView = (TextView) findViewById(R.id.textViewSubjectName);
textView.setText(subject.getSubjectName());
}
private void setQuestionsAndAnswers(int index)
{
currentQuestion = questions.get(index);
// Set question
TextView textViewQuestion = (TextView) findViewById(R.id.textViewQuestion);
textViewQuestion.setText(currentQuestion.getQuestion());
// Set correct answer
correctAnswer = currentQuestion.getCorrectAnswer();
sourceUrl = currentQuestion.getSourceUrl();
sourceText = currentQuestion.getSourceText();
// Set answer #1
initializeButton(answer1, currentQuestion.getAnswer1());
// Set answer #2
initializeButton(answer2, currentQuestion.getAnswer2());
// Set source
TextView textViewSource = (TextView) findViewById(R.id.textViewSource);
textViewSource.setText(sourceText);
textViewSource.setPaintFlags(Paint.UNDERLINE_TEXT_FLAG);
textViewSource.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(sourceUrl));
startActivity(browserIntent);
}
});
// Update progress
updateProgress(index);
}
private void initializeButton(Button button, String answer)
{
button.setText(answer);
button.setTextColor(Color.WHITE);
button.setBackgroundColor(Color.TRANSPARENT);
button.setEnabled(true);
button.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View view)
{
onClickContent(view);
}
});
}
private void onClickContent(View view)
{
Context context = getApplicationContext();
final Button button = (Button) view;
String answer = button.getText().toString();
if (answer.equalsIgnoreCase(correctAnswer))
{
button.setTextColor(Color.GREEN);
try
{
Thread.sleep(1000);
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
if (index == maxIndex)
{
appPreferences.editPreferences(context, Globals.PREFERENCE_KEY + subjectId, true);
playSound(Globals.SOUND_QUIZ_COMPLETED);
Toast toast = Toast.makeText(context, "Quiz \"" + subject.getSubjectName() + "\" finished",Toast.LENGTH_LONG);
toast.show();
finish();
} else
{
playSound(Globals.SOUND_CORRECT_ANSER);
// Go to next question
index++;
setQuestionsAndAnswers(index);
}
} else
{
if (livesLeft == 1)
{
playSound(Globals.SOUND_GAME_OVER);
Toast toast = Toast.makeText(context, "Game over", Toast.LENGTH_LONG);
toast.show();
finish();
} else
{
playSound(Globals.SOUND_WRONG_ANSWER);
button.setTextColor(Color.RED);
button.setEnabled(false);
livesLeft--;
TextView lives = (TextView) findViewById(R.id.textViewLives);
lives.setText("Lives: " + livesLeft);
}
}
}
private void updateProgress(int progress)
{
progressBar.setProgress(progress++);
}
private void playSound(int songId)
{
MediaPlayer mp = MediaPlayer.create(getApplicationContext(), songId);
mp.start();
}
Firstly, Thread.sleep(1000); in your case runs on MAIN thread, causes MAIN thread to sleep, it's not suggested.
You may view.postDelayed to load next question after a delay,
private void onClickContent(View view)
{
Context context = getApplicationContext();
final Button button = (Button) view;
String answer = button.getText().toString();
if (answer.equalsIgnoreCase(correctAnswer))
{
button.setTextColor(Color.GREEN);
if (index == maxIndex)
{
appPreferences.editPreferences(context, Globals.PREFERENCE_KEY + subjectId, true);
playSound(Globals.SOUND_QUIZ_COMPLETED);
Toast toast = Toast.makeText(context, "Quiz \"" + subject.getSubjectName() + "\" finished",Toast.LENGTH_LONG);
toast.show();
finish();
} else
{
playSound(Globals.SOUND_CORRECT_ANSER);
// Go to next question
index++;
// Go to next question after 1000ms
view.postDelayed(new Runnable() {
public void run() {
setQuestionsAndAnswers(index);
}
}, 1000); //here delays 1000ms
}
}
...
}
This is what I use for the same purpose. It should work...
button.setTextColor(Color.GREEN);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
// Reset Color if you want to...
// Start new question here
}
}, 1000);
How to merge following code with Async Task . I see lots of tutorials and make changes in code but unable to do completely. This code is completely fine and working proper but some one advise me to make it Async Task so that when i press button it will take some time to start. so please someone add async task code in it so that its work proper.
Code:-
public class QuestionActivity extends Activity implements OnClickListener{
private Question currentQ;
private GamePlay currentGame;
private CountDownTimer counterTimer;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.question);
processScreen();
}
/**
* Configure current game and get question
*/
private void processScreen()
{
currentGame = ((CYKApplication)getApplication()).getCurrentGame();
currentQ = currentGame.getNextQuestion();
Button nextBtn1 = (Button) findViewById(R.id.answer1);
nextBtn1.setOnClickListener(this);
Button nextBtn2 = (Button) findViewById(R.id.answer2);
nextBtn2.setOnClickListener(this);
Button nextBtn3 = (Button) findViewById(R.id.answer3);
nextBtn3.setOnClickListener(this);
Button nextBtn4 = (Button) findViewById(R.id.answer4);
nextBtn4.setOnClickListener(this);
Button nextBtn5 = (Button) findViewById(R.id.answer5);
nextBtn5.setOnClickListener(this);
/**
* Update the question and answer options..
*/
setQuestions();
}
/**
* 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)));
int score = currentGame.getScore();
String scr = String.valueOf(score);
TextView score1 = (TextView) findViewById(R.id.score);
score1.setText(scr);
counterTimer=new CountDownTimer(15000, 1000) {
public void onFinish() {
if(currentGame.getRound()==20)
System.exit(0);
currentGame.decrementScore();
processScreen();
}
public void onTick(long millisUntilFinished) {
TextView time = (TextView) findViewById(R.id.timers);
time.setText( ""+millisUntilFinished/1000);
}
};
counterTimer.start();
}
#Override
public void onResume() {
super.onResume();
}
#Override
public void onClick(View arg0) {
//Log.d("Questions", "Moving to next question");
if(arg0.getId()==R.id.answer5)
{
new AlertDialog.Builder(this).setMessage("Are you sure?").setCancelable(true).setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int id) {
finish();
}
}).setNegativeButton("No", null).show();
}
else
{
if(!checkAnswer(arg0)) return;
/**
* check if end of game
*/
if (currentGame.isGameOver()){
//Log.d("Questions", "End of game! lets add up the scores..");
//Log.d("Questions", "Questions Correct: " + currentGame.getRight());
//Log.d("Questions", "Questions Wrong: " + currentGame.getWrong());
Intent i = new Intent(this, EndgameActivity.class);
startActivity(i);
finish();
}
else
{
Intent i = new Intent(this, QuestionActivity.class);
finish();
startActivity(i);
}
}
}
#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(View v) {
Button b=(Button) v;
String answer = b.getText().toString();
counterTimer.cancel();
b.setBackgroundResource(R.drawable.ans);
b.setEnabled(false);
//Log.d("Questions", "Valid Checkbox selection made - check if correct");
if (currentQ.getAnswer().equalsIgnoreCase(answer))
{
b.setBackgroundResource(R.drawable.ansgreen);
//Log.d("Questions", "Correct Answer!");
currentGame.incrementScore();
}
else{
b.setBackgroundResource(R.drawable.ansred);
//Log.d("Questions", "Incorrect Answer!");
currentGame.decrementScore1();
}
return true;
}
}
Hope Anyone Can Help me.
Thanks in Advance
Use Runnable :
private static final int START_AFTER_SECONDS = 10;
...
Runnable mRunnable;
Handler mHandler = new Handler();
mRunnable = new Runnable() {
#Override
public void run() {
//DELAYED CODE HERE
}
};
mHandler.postDelayed(mRunnable, START_AFTER_SECONDS * 1000);
AsyncTask is not the right tool for this job. Try this
getHandler().postDelayed(
new Runnable {
void run()
{
methodToCall();
}
}, delayTimeInMilliseconds);