Restoring the instance state of an SQLite quiz app in Android

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
1
down vote

favorite












The following class is the activity of a little SQLite quiz app, which takes care of showing the actual quiz. Other than that the app only has a starting screen.
I want to save the instance state and restore it. It works, but I wonder if the code is too messy now. I am a beginner of course.



Where should I remove redundancy?
How is this overall approach?
I save texts of TextViews, the button and the RadioButtons with the freezesText=true xml attribute.



public class QuizActivity extends AppCompatActivity 
public static final String EXTRA_SCORE = "extraScore";
private static final long COUNTDOWN_IN_MILLIS = 30000;

private static final String KEY_SCORE = "keyScore";
private static final String KEY_QUESTION_COUNT = "keyQuestionCount";
private static final String KEY_MILLIS_LEFT = "keyMillisLeft";
private static final String KEY_QUESTION_LIST = "keyQuestionList";
private static final String KEY_ANSWERED = "keyAnswered";

private TextView textViewQuestion;
private TextView textViewScore;
private TextView textViewQuestionCount;
private TextView textViewCountDown;
private RadioGroup rbGroup;
private RadioButton rb1;
private RadioButton rb2;
private RadioButton rb3;
private Button buttonConfirmNext;

private ColorStateList textColorDefaultRb;
private ColorStateList textColorDefaultCd;

private CountDownTimer countDownTimer;
private long timeLeftInMillis;

private List<Question> questionList;
private int questionCounter;
private int questionCountTotal;
private Question currentQuestion;

private int score;
private boolean answered;

private long backPressedTime;

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

textViewQuestion = findViewById(R.id.text_view_question);
textViewScore = findViewById(R.id.text_view_score);
textViewQuestionCount = findViewById(R.id.text_view_question_count);
textViewCountDown = findViewById(R.id.text_view_countdown);
rbGroup = findViewById(R.id.radio_group);
rb1 = findViewById(R.id.radio_button1);
rb2 = findViewById(R.id.radio_button2);
rb3 = findViewById(R.id.radio_button3);
buttonConfirmNext = findViewById(R.id.button_confirm_next);

textColorDefaultRb = rb1.getTextColors();
textColorDefaultCd = textViewCountDown.getTextColors();

if (savedInstanceState == null)
QuizDbHelper dbHelper = new QuizDbHelper(this);
questionList = dbHelper.getAllQuestions();
questionCountTotal = questionList.size();
Collections.shuffle(questionList);

showNextQuestion();
else
questionList = savedInstanceState.getParcelableArrayList(KEY_QUESTION_LIST);
questionCountTotal = questionList.size();
questionCounter = savedInstanceState.getInt(KEY_QUESTION_COUNT);
currentQuestion = questionList.get(questionCounter-1);
score = savedInstanceState.getInt(KEY_SCORE);
timeLeftInMillis = savedInstanceState.getLong(KEY_MILLIS_LEFT);
answered = savedInstanceState.getBoolean(KEY_ANSWERED);

if (!answered)
startCountDown();
else
showSolution();



buttonConfirmNext.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
if (!answered)
if (rb1.isChecked() else
showNextQuestion();


);


private void showNextQuestion()
rb1.setTextColor(textColorDefaultRb);
rb2.setTextColor(textColorDefaultRb);
rb3.setTextColor(textColorDefaultRb);
rbGroup.clearCheck();

if (questionCounter < questionCountTotal)
currentQuestion = questionList.get(questionCounter);

textViewQuestion.setText(currentQuestion.getQuestion());
rb1.setText(currentQuestion.getOption1());
rb2.setText(currentQuestion.getOption2());
rb3.setText(currentQuestion.getOption3());

questionCounter++;
textViewQuestionCount.setText("Question: " + questionCounter + "/" + questionCountTotal);
answered = false;
buttonConfirmNext.setText("Confirm");

timeLeftInMillis = COUNTDOWN_IN_MILLIS;
startCountDown();
else
finishQuiz();



private void startCountDown()
countDownTimer = new CountDownTimer(timeLeftInMillis, 1000)
@Override
public void onTick(long millisUntilFinished)
timeLeftInMillis = millisUntilFinished;
updateCountDownText();


@Override
public void onFinish()
timeLeftInMillis = 0;
updateCountDownText();
checkAnswer();

.start();


private void updateCountDownText()
int minutes = (int) (timeLeftInMillis / 1000) / 60;
int seconds = (int) (timeLeftInMillis / 1000) % 60;

String timeFormatted = String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds);

textViewCountDown.setText(timeFormatted);

if (timeLeftInMillis < 10000)
textViewCountDown.setTextColor(Color.RED);
else
textViewCountDown.setTextColor(textColorDefaultCd);



private void checkAnswer()
answered = true;

countDownTimer.cancel();

RadioButton rbSelected = findViewById(rbGroup.getCheckedRadioButtonId());
int answerNr = rbGroup.indexOfChild(rbSelected) + 1;

if (answerNr == currentQuestion.getAnswerNr())
score++;
textViewScore.setText("Score: " + score);


showSolution();


private void showSolution()
rb1.setTextColor(Color.RED);
rb2.setTextColor(Color.RED);
rb3.setTextColor(Color.RED);

switch (currentQuestion.getAnswerNr())
case 1:
rb1.setTextColor(Color.GREEN);
textViewQuestion.setText("Answer 1 is correct");
break;
case 2:
rb2.setTextColor(Color.GREEN);
textViewQuestion.setText("Answer 2 is correct");
break;
case 3:
rb3.setTextColor(Color.GREEN);
textViewQuestion.setText("Answer 3 is correct");
break;


if (questionCounter < questionCountTotal)
buttonConfirmNext.setText("Next");
else
buttonConfirmNext.setText("Finish");



private void finishQuiz()
Intent resultIntent = new Intent();
resultIntent.putExtra(EXTRA_SCORE, score);
setResult(RESULT_OK, resultIntent);
finish();


@Override
public void onBackPressed()
if (backPressedTime + 2000 > System.currentTimeMillis())
finishQuiz();
else
Toast.makeText(this, "Press back again to finish", Toast.LENGTH_SHORT).show();


backPressedTime = System.currentTimeMillis();


@Override
protected void onDestroy()
super.onDestroy();
if (countDownTimer != null)
countDownTimer.cancel();



@Override
protected void onSaveInstanceState(Bundle outState)
super.onSaveInstanceState(outState);
outState.putInt(KEY_SCORE, score);
outState.putInt(KEY_QUESTION_COUNT, questionCounter);
outState.putLong(KEY_MILLIS_LEFT, timeLeftInMillis);
outState.putParcelableArrayList(KEY_QUESTION_LIST, (ArrayList<? extends Parcelable>) questionList);
outState.putBoolean(KEY_ANSWERED, answered);








share|improve this question



























    up vote
    1
    down vote

    favorite












    The following class is the activity of a little SQLite quiz app, which takes care of showing the actual quiz. Other than that the app only has a starting screen.
    I want to save the instance state and restore it. It works, but I wonder if the code is too messy now. I am a beginner of course.



    Where should I remove redundancy?
    How is this overall approach?
    I save texts of TextViews, the button and the RadioButtons with the freezesText=true xml attribute.



    public class QuizActivity extends AppCompatActivity 
    public static final String EXTRA_SCORE = "extraScore";
    private static final long COUNTDOWN_IN_MILLIS = 30000;

    private static final String KEY_SCORE = "keyScore";
    private static final String KEY_QUESTION_COUNT = "keyQuestionCount";
    private static final String KEY_MILLIS_LEFT = "keyMillisLeft";
    private static final String KEY_QUESTION_LIST = "keyQuestionList";
    private static final String KEY_ANSWERED = "keyAnswered";

    private TextView textViewQuestion;
    private TextView textViewScore;
    private TextView textViewQuestionCount;
    private TextView textViewCountDown;
    private RadioGroup rbGroup;
    private RadioButton rb1;
    private RadioButton rb2;
    private RadioButton rb3;
    private Button buttonConfirmNext;

    private ColorStateList textColorDefaultRb;
    private ColorStateList textColorDefaultCd;

    private CountDownTimer countDownTimer;
    private long timeLeftInMillis;

    private List<Question> questionList;
    private int questionCounter;
    private int questionCountTotal;
    private Question currentQuestion;

    private int score;
    private boolean answered;

    private long backPressedTime;

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

    textViewQuestion = findViewById(R.id.text_view_question);
    textViewScore = findViewById(R.id.text_view_score);
    textViewQuestionCount = findViewById(R.id.text_view_question_count);
    textViewCountDown = findViewById(R.id.text_view_countdown);
    rbGroup = findViewById(R.id.radio_group);
    rb1 = findViewById(R.id.radio_button1);
    rb2 = findViewById(R.id.radio_button2);
    rb3 = findViewById(R.id.radio_button3);
    buttonConfirmNext = findViewById(R.id.button_confirm_next);

    textColorDefaultRb = rb1.getTextColors();
    textColorDefaultCd = textViewCountDown.getTextColors();

    if (savedInstanceState == null)
    QuizDbHelper dbHelper = new QuizDbHelper(this);
    questionList = dbHelper.getAllQuestions();
    questionCountTotal = questionList.size();
    Collections.shuffle(questionList);

    showNextQuestion();
    else
    questionList = savedInstanceState.getParcelableArrayList(KEY_QUESTION_LIST);
    questionCountTotal = questionList.size();
    questionCounter = savedInstanceState.getInt(KEY_QUESTION_COUNT);
    currentQuestion = questionList.get(questionCounter-1);
    score = savedInstanceState.getInt(KEY_SCORE);
    timeLeftInMillis = savedInstanceState.getLong(KEY_MILLIS_LEFT);
    answered = savedInstanceState.getBoolean(KEY_ANSWERED);

    if (!answered)
    startCountDown();
    else
    showSolution();



    buttonConfirmNext.setOnClickListener(new View.OnClickListener()
    @Override
    public void onClick(View v)
    if (!answered)
    if (rb1.isChecked() else
    showNextQuestion();


    );


    private void showNextQuestion()
    rb1.setTextColor(textColorDefaultRb);
    rb2.setTextColor(textColorDefaultRb);
    rb3.setTextColor(textColorDefaultRb);
    rbGroup.clearCheck();

    if (questionCounter < questionCountTotal)
    currentQuestion = questionList.get(questionCounter);

    textViewQuestion.setText(currentQuestion.getQuestion());
    rb1.setText(currentQuestion.getOption1());
    rb2.setText(currentQuestion.getOption2());
    rb3.setText(currentQuestion.getOption3());

    questionCounter++;
    textViewQuestionCount.setText("Question: " + questionCounter + "/" + questionCountTotal);
    answered = false;
    buttonConfirmNext.setText("Confirm");

    timeLeftInMillis = COUNTDOWN_IN_MILLIS;
    startCountDown();
    else
    finishQuiz();



    private void startCountDown()
    countDownTimer = new CountDownTimer(timeLeftInMillis, 1000)
    @Override
    public void onTick(long millisUntilFinished)
    timeLeftInMillis = millisUntilFinished;
    updateCountDownText();


    @Override
    public void onFinish()
    timeLeftInMillis = 0;
    updateCountDownText();
    checkAnswer();

    .start();


    private void updateCountDownText()
    int minutes = (int) (timeLeftInMillis / 1000) / 60;
    int seconds = (int) (timeLeftInMillis / 1000) % 60;

    String timeFormatted = String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds);

    textViewCountDown.setText(timeFormatted);

    if (timeLeftInMillis < 10000)
    textViewCountDown.setTextColor(Color.RED);
    else
    textViewCountDown.setTextColor(textColorDefaultCd);



    private void checkAnswer()
    answered = true;

    countDownTimer.cancel();

    RadioButton rbSelected = findViewById(rbGroup.getCheckedRadioButtonId());
    int answerNr = rbGroup.indexOfChild(rbSelected) + 1;

    if (answerNr == currentQuestion.getAnswerNr())
    score++;
    textViewScore.setText("Score: " + score);


    showSolution();


    private void showSolution()
    rb1.setTextColor(Color.RED);
    rb2.setTextColor(Color.RED);
    rb3.setTextColor(Color.RED);

    switch (currentQuestion.getAnswerNr())
    case 1:
    rb1.setTextColor(Color.GREEN);
    textViewQuestion.setText("Answer 1 is correct");
    break;
    case 2:
    rb2.setTextColor(Color.GREEN);
    textViewQuestion.setText("Answer 2 is correct");
    break;
    case 3:
    rb3.setTextColor(Color.GREEN);
    textViewQuestion.setText("Answer 3 is correct");
    break;


    if (questionCounter < questionCountTotal)
    buttonConfirmNext.setText("Next");
    else
    buttonConfirmNext.setText("Finish");



    private void finishQuiz()
    Intent resultIntent = new Intent();
    resultIntent.putExtra(EXTRA_SCORE, score);
    setResult(RESULT_OK, resultIntent);
    finish();


    @Override
    public void onBackPressed()
    if (backPressedTime + 2000 > System.currentTimeMillis())
    finishQuiz();
    else
    Toast.makeText(this, "Press back again to finish", Toast.LENGTH_SHORT).show();


    backPressedTime = System.currentTimeMillis();


    @Override
    protected void onDestroy()
    super.onDestroy();
    if (countDownTimer != null)
    countDownTimer.cancel();



    @Override
    protected void onSaveInstanceState(Bundle outState)
    super.onSaveInstanceState(outState);
    outState.putInt(KEY_SCORE, score);
    outState.putInt(KEY_QUESTION_COUNT, questionCounter);
    outState.putLong(KEY_MILLIS_LEFT, timeLeftInMillis);
    outState.putParcelableArrayList(KEY_QUESTION_LIST, (ArrayList<? extends Parcelable>) questionList);
    outState.putBoolean(KEY_ANSWERED, answered);








    share|improve this question























      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      The following class is the activity of a little SQLite quiz app, which takes care of showing the actual quiz. Other than that the app only has a starting screen.
      I want to save the instance state and restore it. It works, but I wonder if the code is too messy now. I am a beginner of course.



      Where should I remove redundancy?
      How is this overall approach?
      I save texts of TextViews, the button and the RadioButtons with the freezesText=true xml attribute.



      public class QuizActivity extends AppCompatActivity 
      public static final String EXTRA_SCORE = "extraScore";
      private static final long COUNTDOWN_IN_MILLIS = 30000;

      private static final String KEY_SCORE = "keyScore";
      private static final String KEY_QUESTION_COUNT = "keyQuestionCount";
      private static final String KEY_MILLIS_LEFT = "keyMillisLeft";
      private static final String KEY_QUESTION_LIST = "keyQuestionList";
      private static final String KEY_ANSWERED = "keyAnswered";

      private TextView textViewQuestion;
      private TextView textViewScore;
      private TextView textViewQuestionCount;
      private TextView textViewCountDown;
      private RadioGroup rbGroup;
      private RadioButton rb1;
      private RadioButton rb2;
      private RadioButton rb3;
      private Button buttonConfirmNext;

      private ColorStateList textColorDefaultRb;
      private ColorStateList textColorDefaultCd;

      private CountDownTimer countDownTimer;
      private long timeLeftInMillis;

      private List<Question> questionList;
      private int questionCounter;
      private int questionCountTotal;
      private Question currentQuestion;

      private int score;
      private boolean answered;

      private long backPressedTime;

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

      textViewQuestion = findViewById(R.id.text_view_question);
      textViewScore = findViewById(R.id.text_view_score);
      textViewQuestionCount = findViewById(R.id.text_view_question_count);
      textViewCountDown = findViewById(R.id.text_view_countdown);
      rbGroup = findViewById(R.id.radio_group);
      rb1 = findViewById(R.id.radio_button1);
      rb2 = findViewById(R.id.radio_button2);
      rb3 = findViewById(R.id.radio_button3);
      buttonConfirmNext = findViewById(R.id.button_confirm_next);

      textColorDefaultRb = rb1.getTextColors();
      textColorDefaultCd = textViewCountDown.getTextColors();

      if (savedInstanceState == null)
      QuizDbHelper dbHelper = new QuizDbHelper(this);
      questionList = dbHelper.getAllQuestions();
      questionCountTotal = questionList.size();
      Collections.shuffle(questionList);

      showNextQuestion();
      else
      questionList = savedInstanceState.getParcelableArrayList(KEY_QUESTION_LIST);
      questionCountTotal = questionList.size();
      questionCounter = savedInstanceState.getInt(KEY_QUESTION_COUNT);
      currentQuestion = questionList.get(questionCounter-1);
      score = savedInstanceState.getInt(KEY_SCORE);
      timeLeftInMillis = savedInstanceState.getLong(KEY_MILLIS_LEFT);
      answered = savedInstanceState.getBoolean(KEY_ANSWERED);

      if (!answered)
      startCountDown();
      else
      showSolution();



      buttonConfirmNext.setOnClickListener(new View.OnClickListener()
      @Override
      public void onClick(View v)
      if (!answered)
      if (rb1.isChecked() else
      showNextQuestion();


      );


      private void showNextQuestion()
      rb1.setTextColor(textColorDefaultRb);
      rb2.setTextColor(textColorDefaultRb);
      rb3.setTextColor(textColorDefaultRb);
      rbGroup.clearCheck();

      if (questionCounter < questionCountTotal)
      currentQuestion = questionList.get(questionCounter);

      textViewQuestion.setText(currentQuestion.getQuestion());
      rb1.setText(currentQuestion.getOption1());
      rb2.setText(currentQuestion.getOption2());
      rb3.setText(currentQuestion.getOption3());

      questionCounter++;
      textViewQuestionCount.setText("Question: " + questionCounter + "/" + questionCountTotal);
      answered = false;
      buttonConfirmNext.setText("Confirm");

      timeLeftInMillis = COUNTDOWN_IN_MILLIS;
      startCountDown();
      else
      finishQuiz();



      private void startCountDown()
      countDownTimer = new CountDownTimer(timeLeftInMillis, 1000)
      @Override
      public void onTick(long millisUntilFinished)
      timeLeftInMillis = millisUntilFinished;
      updateCountDownText();


      @Override
      public void onFinish()
      timeLeftInMillis = 0;
      updateCountDownText();
      checkAnswer();

      .start();


      private void updateCountDownText()
      int minutes = (int) (timeLeftInMillis / 1000) / 60;
      int seconds = (int) (timeLeftInMillis / 1000) % 60;

      String timeFormatted = String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds);

      textViewCountDown.setText(timeFormatted);

      if (timeLeftInMillis < 10000)
      textViewCountDown.setTextColor(Color.RED);
      else
      textViewCountDown.setTextColor(textColorDefaultCd);



      private void checkAnswer()
      answered = true;

      countDownTimer.cancel();

      RadioButton rbSelected = findViewById(rbGroup.getCheckedRadioButtonId());
      int answerNr = rbGroup.indexOfChild(rbSelected) + 1;

      if (answerNr == currentQuestion.getAnswerNr())
      score++;
      textViewScore.setText("Score: " + score);


      showSolution();


      private void showSolution()
      rb1.setTextColor(Color.RED);
      rb2.setTextColor(Color.RED);
      rb3.setTextColor(Color.RED);

      switch (currentQuestion.getAnswerNr())
      case 1:
      rb1.setTextColor(Color.GREEN);
      textViewQuestion.setText("Answer 1 is correct");
      break;
      case 2:
      rb2.setTextColor(Color.GREEN);
      textViewQuestion.setText("Answer 2 is correct");
      break;
      case 3:
      rb3.setTextColor(Color.GREEN);
      textViewQuestion.setText("Answer 3 is correct");
      break;


      if (questionCounter < questionCountTotal)
      buttonConfirmNext.setText("Next");
      else
      buttonConfirmNext.setText("Finish");



      private void finishQuiz()
      Intent resultIntent = new Intent();
      resultIntent.putExtra(EXTRA_SCORE, score);
      setResult(RESULT_OK, resultIntent);
      finish();


      @Override
      public void onBackPressed()
      if (backPressedTime + 2000 > System.currentTimeMillis())
      finishQuiz();
      else
      Toast.makeText(this, "Press back again to finish", Toast.LENGTH_SHORT).show();


      backPressedTime = System.currentTimeMillis();


      @Override
      protected void onDestroy()
      super.onDestroy();
      if (countDownTimer != null)
      countDownTimer.cancel();



      @Override
      protected void onSaveInstanceState(Bundle outState)
      super.onSaveInstanceState(outState);
      outState.putInt(KEY_SCORE, score);
      outState.putInt(KEY_QUESTION_COUNT, questionCounter);
      outState.putLong(KEY_MILLIS_LEFT, timeLeftInMillis);
      outState.putParcelableArrayList(KEY_QUESTION_LIST, (ArrayList<? extends Parcelable>) questionList);
      outState.putBoolean(KEY_ANSWERED, answered);








      share|improve this question













      The following class is the activity of a little SQLite quiz app, which takes care of showing the actual quiz. Other than that the app only has a starting screen.
      I want to save the instance state and restore it. It works, but I wonder if the code is too messy now. I am a beginner of course.



      Where should I remove redundancy?
      How is this overall approach?
      I save texts of TextViews, the button and the RadioButtons with the freezesText=true xml attribute.



      public class QuizActivity extends AppCompatActivity 
      public static final String EXTRA_SCORE = "extraScore";
      private static final long COUNTDOWN_IN_MILLIS = 30000;

      private static final String KEY_SCORE = "keyScore";
      private static final String KEY_QUESTION_COUNT = "keyQuestionCount";
      private static final String KEY_MILLIS_LEFT = "keyMillisLeft";
      private static final String KEY_QUESTION_LIST = "keyQuestionList";
      private static final String KEY_ANSWERED = "keyAnswered";

      private TextView textViewQuestion;
      private TextView textViewScore;
      private TextView textViewQuestionCount;
      private TextView textViewCountDown;
      private RadioGroup rbGroup;
      private RadioButton rb1;
      private RadioButton rb2;
      private RadioButton rb3;
      private Button buttonConfirmNext;

      private ColorStateList textColorDefaultRb;
      private ColorStateList textColorDefaultCd;

      private CountDownTimer countDownTimer;
      private long timeLeftInMillis;

      private List<Question> questionList;
      private int questionCounter;
      private int questionCountTotal;
      private Question currentQuestion;

      private int score;
      private boolean answered;

      private long backPressedTime;

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

      textViewQuestion = findViewById(R.id.text_view_question);
      textViewScore = findViewById(R.id.text_view_score);
      textViewQuestionCount = findViewById(R.id.text_view_question_count);
      textViewCountDown = findViewById(R.id.text_view_countdown);
      rbGroup = findViewById(R.id.radio_group);
      rb1 = findViewById(R.id.radio_button1);
      rb2 = findViewById(R.id.radio_button2);
      rb3 = findViewById(R.id.radio_button3);
      buttonConfirmNext = findViewById(R.id.button_confirm_next);

      textColorDefaultRb = rb1.getTextColors();
      textColorDefaultCd = textViewCountDown.getTextColors();

      if (savedInstanceState == null)
      QuizDbHelper dbHelper = new QuizDbHelper(this);
      questionList = dbHelper.getAllQuestions();
      questionCountTotal = questionList.size();
      Collections.shuffle(questionList);

      showNextQuestion();
      else
      questionList = savedInstanceState.getParcelableArrayList(KEY_QUESTION_LIST);
      questionCountTotal = questionList.size();
      questionCounter = savedInstanceState.getInt(KEY_QUESTION_COUNT);
      currentQuestion = questionList.get(questionCounter-1);
      score = savedInstanceState.getInt(KEY_SCORE);
      timeLeftInMillis = savedInstanceState.getLong(KEY_MILLIS_LEFT);
      answered = savedInstanceState.getBoolean(KEY_ANSWERED);

      if (!answered)
      startCountDown();
      else
      showSolution();



      buttonConfirmNext.setOnClickListener(new View.OnClickListener()
      @Override
      public void onClick(View v)
      if (!answered)
      if (rb1.isChecked() else
      showNextQuestion();


      );


      private void showNextQuestion()
      rb1.setTextColor(textColorDefaultRb);
      rb2.setTextColor(textColorDefaultRb);
      rb3.setTextColor(textColorDefaultRb);
      rbGroup.clearCheck();

      if (questionCounter < questionCountTotal)
      currentQuestion = questionList.get(questionCounter);

      textViewQuestion.setText(currentQuestion.getQuestion());
      rb1.setText(currentQuestion.getOption1());
      rb2.setText(currentQuestion.getOption2());
      rb3.setText(currentQuestion.getOption3());

      questionCounter++;
      textViewQuestionCount.setText("Question: " + questionCounter + "/" + questionCountTotal);
      answered = false;
      buttonConfirmNext.setText("Confirm");

      timeLeftInMillis = COUNTDOWN_IN_MILLIS;
      startCountDown();
      else
      finishQuiz();



      private void startCountDown()
      countDownTimer = new CountDownTimer(timeLeftInMillis, 1000)
      @Override
      public void onTick(long millisUntilFinished)
      timeLeftInMillis = millisUntilFinished;
      updateCountDownText();


      @Override
      public void onFinish()
      timeLeftInMillis = 0;
      updateCountDownText();
      checkAnswer();

      .start();


      private void updateCountDownText()
      int minutes = (int) (timeLeftInMillis / 1000) / 60;
      int seconds = (int) (timeLeftInMillis / 1000) % 60;

      String timeFormatted = String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds);

      textViewCountDown.setText(timeFormatted);

      if (timeLeftInMillis < 10000)
      textViewCountDown.setTextColor(Color.RED);
      else
      textViewCountDown.setTextColor(textColorDefaultCd);



      private void checkAnswer()
      answered = true;

      countDownTimer.cancel();

      RadioButton rbSelected = findViewById(rbGroup.getCheckedRadioButtonId());
      int answerNr = rbGroup.indexOfChild(rbSelected) + 1;

      if (answerNr == currentQuestion.getAnswerNr())
      score++;
      textViewScore.setText("Score: " + score);


      showSolution();


      private void showSolution()
      rb1.setTextColor(Color.RED);
      rb2.setTextColor(Color.RED);
      rb3.setTextColor(Color.RED);

      switch (currentQuestion.getAnswerNr())
      case 1:
      rb1.setTextColor(Color.GREEN);
      textViewQuestion.setText("Answer 1 is correct");
      break;
      case 2:
      rb2.setTextColor(Color.GREEN);
      textViewQuestion.setText("Answer 2 is correct");
      break;
      case 3:
      rb3.setTextColor(Color.GREEN);
      textViewQuestion.setText("Answer 3 is correct");
      break;


      if (questionCounter < questionCountTotal)
      buttonConfirmNext.setText("Next");
      else
      buttonConfirmNext.setText("Finish");



      private void finishQuiz()
      Intent resultIntent = new Intent();
      resultIntent.putExtra(EXTRA_SCORE, score);
      setResult(RESULT_OK, resultIntent);
      finish();


      @Override
      public void onBackPressed()
      if (backPressedTime + 2000 > System.currentTimeMillis())
      finishQuiz();
      else
      Toast.makeText(this, "Press back again to finish", Toast.LENGTH_SHORT).show();


      backPressedTime = System.currentTimeMillis();


      @Override
      protected void onDestroy()
      super.onDestroy();
      if (countDownTimer != null)
      countDownTimer.cancel();



      @Override
      protected void onSaveInstanceState(Bundle outState)
      super.onSaveInstanceState(outState);
      outState.putInt(KEY_SCORE, score);
      outState.putInt(KEY_QUESTION_COUNT, questionCounter);
      outState.putLong(KEY_MILLIS_LEFT, timeLeftInMillis);
      outState.putParcelableArrayList(KEY_QUESTION_LIST, (ArrayList<? extends Parcelable>) questionList);
      outState.putBoolean(KEY_ANSWERED, answered);










      share|improve this question












      share|improve this question




      share|improve this question








      edited Feb 26 at 1:22









      200_success

      123k14142399




      123k14142399









      asked Feb 25 at 23:13









      Florian Walther

      1415




      1415




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          0
          down vote













          some minor things,



          when you use showNextQuestion you should split up that method into the three sub-methods to clarify what you're doing:



          private void showNextQuestion()
          currentQuestion = getNextQuestion();
          showQuestion(currentQuestion );
          startCountDown();



          that would make showNextQuestionto a mere delegation-method and it would be very clearly what this method does.



          and if you did it this way you can re-use these methods during onCreate:



          public void onCreate(Bundle savedInstanceState) 

          ...

          if (savedInstanceState == null)
          loadQuestionsFromDb();
          else
          loadQuestionsFromSavedInstance(savedInstanceState);

          showQuestion(currentQuestion); //as mentioned above

          if (answered)
          //FIXME you don't show current score
          showSolution();
          else
          startCountDown();


          ...




          remove the counting part of checkAnswer into a seperate methode - thus makes the checkAnswermethod a clean delegation method



          private void checkAnswer() 
          answered = true;
          countDownTimer.cancel();
          score = score + countCurrentScore();
          textViewScore.setText("Score: " + score);
          showSolution();



          there are also some cosmetic things, maybe you should remove the blanks or shorten code when possible



          if (timeLeftInMillis < 10000) 
          textViewCountDown.setTextColor(Color.RED);
          else
          textViewCountDown.setTextColor(textColorDefaultCd);



          into



          textViewCountDown.setTextColor(timeLeftInMillis<10000?Color.RED:textColorDefaultCd); 


          but thats no show stopper (there are some more issues of this type - but nevermind)






          share|improve this answer























          • I'd like to disagree on "you should remove the blanks or shorten code when possible". Readablity/understandability goes before shortness. The conditional expression would be much better readable with spaces and on a separate line: Color color = timeLeftInMillis < 10000 ? Color.RED : textColorDefaultCd;
            – RoToRa
            Mar 2 at 7:59










          • uhm - i tried to point out that these changes are cosmetic proposals and depend on the OPs own view of things - i said maybe to emphase this personal view of mine and even added the no show stopper-part ^_^ @RoToRa - in my opinion i do not see any need to first get the color and then second set the text color with it - i for myself would simply set the text color directly... but what do i know ^^
            – Martin Frank
            Mar 2 at 8:02











          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f188343%2frestoring-the-instance-state-of-an-sqlite-quiz-app-in-android%23new-answer', 'question_page');

          );

          Post as a guest






























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          0
          down vote













          some minor things,



          when you use showNextQuestion you should split up that method into the three sub-methods to clarify what you're doing:



          private void showNextQuestion()
          currentQuestion = getNextQuestion();
          showQuestion(currentQuestion );
          startCountDown();



          that would make showNextQuestionto a mere delegation-method and it would be very clearly what this method does.



          and if you did it this way you can re-use these methods during onCreate:



          public void onCreate(Bundle savedInstanceState) 

          ...

          if (savedInstanceState == null)
          loadQuestionsFromDb();
          else
          loadQuestionsFromSavedInstance(savedInstanceState);

          showQuestion(currentQuestion); //as mentioned above

          if (answered)
          //FIXME you don't show current score
          showSolution();
          else
          startCountDown();


          ...




          remove the counting part of checkAnswer into a seperate methode - thus makes the checkAnswermethod a clean delegation method



          private void checkAnswer() 
          answered = true;
          countDownTimer.cancel();
          score = score + countCurrentScore();
          textViewScore.setText("Score: " + score);
          showSolution();



          there are also some cosmetic things, maybe you should remove the blanks or shorten code when possible



          if (timeLeftInMillis < 10000) 
          textViewCountDown.setTextColor(Color.RED);
          else
          textViewCountDown.setTextColor(textColorDefaultCd);



          into



          textViewCountDown.setTextColor(timeLeftInMillis<10000?Color.RED:textColorDefaultCd); 


          but thats no show stopper (there are some more issues of this type - but nevermind)






          share|improve this answer























          • I'd like to disagree on "you should remove the blanks or shorten code when possible". Readablity/understandability goes before shortness. The conditional expression would be much better readable with spaces and on a separate line: Color color = timeLeftInMillis < 10000 ? Color.RED : textColorDefaultCd;
            – RoToRa
            Mar 2 at 7:59










          • uhm - i tried to point out that these changes are cosmetic proposals and depend on the OPs own view of things - i said maybe to emphase this personal view of mine and even added the no show stopper-part ^_^ @RoToRa - in my opinion i do not see any need to first get the color and then second set the text color with it - i for myself would simply set the text color directly... but what do i know ^^
            – Martin Frank
            Mar 2 at 8:02















          up vote
          0
          down vote













          some minor things,



          when you use showNextQuestion you should split up that method into the three sub-methods to clarify what you're doing:



          private void showNextQuestion()
          currentQuestion = getNextQuestion();
          showQuestion(currentQuestion );
          startCountDown();



          that would make showNextQuestionto a mere delegation-method and it would be very clearly what this method does.



          and if you did it this way you can re-use these methods during onCreate:



          public void onCreate(Bundle savedInstanceState) 

          ...

          if (savedInstanceState == null)
          loadQuestionsFromDb();
          else
          loadQuestionsFromSavedInstance(savedInstanceState);

          showQuestion(currentQuestion); //as mentioned above

          if (answered)
          //FIXME you don't show current score
          showSolution();
          else
          startCountDown();


          ...




          remove the counting part of checkAnswer into a seperate methode - thus makes the checkAnswermethod a clean delegation method



          private void checkAnswer() 
          answered = true;
          countDownTimer.cancel();
          score = score + countCurrentScore();
          textViewScore.setText("Score: " + score);
          showSolution();



          there are also some cosmetic things, maybe you should remove the blanks or shorten code when possible



          if (timeLeftInMillis < 10000) 
          textViewCountDown.setTextColor(Color.RED);
          else
          textViewCountDown.setTextColor(textColorDefaultCd);



          into



          textViewCountDown.setTextColor(timeLeftInMillis<10000?Color.RED:textColorDefaultCd); 


          but thats no show stopper (there are some more issues of this type - but nevermind)






          share|improve this answer























          • I'd like to disagree on "you should remove the blanks or shorten code when possible". Readablity/understandability goes before shortness. The conditional expression would be much better readable with spaces and on a separate line: Color color = timeLeftInMillis < 10000 ? Color.RED : textColorDefaultCd;
            – RoToRa
            Mar 2 at 7:59










          • uhm - i tried to point out that these changes are cosmetic proposals and depend on the OPs own view of things - i said maybe to emphase this personal view of mine and even added the no show stopper-part ^_^ @RoToRa - in my opinion i do not see any need to first get the color and then second set the text color with it - i for myself would simply set the text color directly... but what do i know ^^
            – Martin Frank
            Mar 2 at 8:02













          up vote
          0
          down vote










          up vote
          0
          down vote









          some minor things,



          when you use showNextQuestion you should split up that method into the three sub-methods to clarify what you're doing:



          private void showNextQuestion()
          currentQuestion = getNextQuestion();
          showQuestion(currentQuestion );
          startCountDown();



          that would make showNextQuestionto a mere delegation-method and it would be very clearly what this method does.



          and if you did it this way you can re-use these methods during onCreate:



          public void onCreate(Bundle savedInstanceState) 

          ...

          if (savedInstanceState == null)
          loadQuestionsFromDb();
          else
          loadQuestionsFromSavedInstance(savedInstanceState);

          showQuestion(currentQuestion); //as mentioned above

          if (answered)
          //FIXME you don't show current score
          showSolution();
          else
          startCountDown();


          ...




          remove the counting part of checkAnswer into a seperate methode - thus makes the checkAnswermethod a clean delegation method



          private void checkAnswer() 
          answered = true;
          countDownTimer.cancel();
          score = score + countCurrentScore();
          textViewScore.setText("Score: " + score);
          showSolution();



          there are also some cosmetic things, maybe you should remove the blanks or shorten code when possible



          if (timeLeftInMillis < 10000) 
          textViewCountDown.setTextColor(Color.RED);
          else
          textViewCountDown.setTextColor(textColorDefaultCd);



          into



          textViewCountDown.setTextColor(timeLeftInMillis<10000?Color.RED:textColorDefaultCd); 


          but thats no show stopper (there are some more issues of this type - but nevermind)






          share|improve this answer















          some minor things,



          when you use showNextQuestion you should split up that method into the three sub-methods to clarify what you're doing:



          private void showNextQuestion()
          currentQuestion = getNextQuestion();
          showQuestion(currentQuestion );
          startCountDown();



          that would make showNextQuestionto a mere delegation-method and it would be very clearly what this method does.



          and if you did it this way you can re-use these methods during onCreate:



          public void onCreate(Bundle savedInstanceState) 

          ...

          if (savedInstanceState == null)
          loadQuestionsFromDb();
          else
          loadQuestionsFromSavedInstance(savedInstanceState);

          showQuestion(currentQuestion); //as mentioned above

          if (answered)
          //FIXME you don't show current score
          showSolution();
          else
          startCountDown();


          ...




          remove the counting part of checkAnswer into a seperate methode - thus makes the checkAnswermethod a clean delegation method



          private void checkAnswer() 
          answered = true;
          countDownTimer.cancel();
          score = score + countCurrentScore();
          textViewScore.setText("Score: " + score);
          showSolution();



          there are also some cosmetic things, maybe you should remove the blanks or shorten code when possible



          if (timeLeftInMillis < 10000) 
          textViewCountDown.setTextColor(Color.RED);
          else
          textViewCountDown.setTextColor(textColorDefaultCd);



          into



          textViewCountDown.setTextColor(timeLeftInMillis<10000?Color.RED:textColorDefaultCd); 


          but thats no show stopper (there are some more issues of this type - but nevermind)







          share|improve this answer















          share|improve this answer



          share|improve this answer








          edited Mar 2 at 5:47


























          answered Mar 1 at 11:24









          Martin Frank

          522315




          522315











          • I'd like to disagree on "you should remove the blanks or shorten code when possible". Readablity/understandability goes before shortness. The conditional expression would be much better readable with spaces and on a separate line: Color color = timeLeftInMillis < 10000 ? Color.RED : textColorDefaultCd;
            – RoToRa
            Mar 2 at 7:59










          • uhm - i tried to point out that these changes are cosmetic proposals and depend on the OPs own view of things - i said maybe to emphase this personal view of mine and even added the no show stopper-part ^_^ @RoToRa - in my opinion i do not see any need to first get the color and then second set the text color with it - i for myself would simply set the text color directly... but what do i know ^^
            – Martin Frank
            Mar 2 at 8:02

















          • I'd like to disagree on "you should remove the blanks or shorten code when possible". Readablity/understandability goes before shortness. The conditional expression would be much better readable with spaces and on a separate line: Color color = timeLeftInMillis < 10000 ? Color.RED : textColorDefaultCd;
            – RoToRa
            Mar 2 at 7:59










          • uhm - i tried to point out that these changes are cosmetic proposals and depend on the OPs own view of things - i said maybe to emphase this personal view of mine and even added the no show stopper-part ^_^ @RoToRa - in my opinion i do not see any need to first get the color and then second set the text color with it - i for myself would simply set the text color directly... but what do i know ^^
            – Martin Frank
            Mar 2 at 8:02
















          I'd like to disagree on "you should remove the blanks or shorten code when possible". Readablity/understandability goes before shortness. The conditional expression would be much better readable with spaces and on a separate line: Color color = timeLeftInMillis < 10000 ? Color.RED : textColorDefaultCd;
          – RoToRa
          Mar 2 at 7:59




          I'd like to disagree on "you should remove the blanks or shorten code when possible". Readablity/understandability goes before shortness. The conditional expression would be much better readable with spaces and on a separate line: Color color = timeLeftInMillis < 10000 ? Color.RED : textColorDefaultCd;
          – RoToRa
          Mar 2 at 7:59












          uhm - i tried to point out that these changes are cosmetic proposals and depend on the OPs own view of things - i said maybe to emphase this personal view of mine and even added the no show stopper-part ^_^ @RoToRa - in my opinion i do not see any need to first get the color and then second set the text color with it - i for myself would simply set the text color directly... but what do i know ^^
          – Martin Frank
          Mar 2 at 8:02





          uhm - i tried to point out that these changes are cosmetic proposals and depend on the OPs own view of things - i said maybe to emphase this personal view of mine and even added the no show stopper-part ^_^ @RoToRa - in my opinion i do not see any need to first get the color and then second set the text color with it - i for myself would simply set the text color directly... but what do i know ^^
          – Martin Frank
          Mar 2 at 8:02













           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f188343%2frestoring-the-instance-state-of-an-sqlite-quiz-app-in-android%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Greedy Best First Search implementation in Rust

          Function to Return a JSON Like Objects Using VBA Collections and Arrays

          C++11 CLH Lock Implementation