Sai Sai - 3 months ago 21
Android Question

Losing data when rotating screen

So I've implemented a

saveInstanceState
method but I don't know if I'm doing it wrong.

What's happening is that when the screen is rotated the question being displayed becomes the first one from the list. But the weird part is that when the question is answered the app is skipping a question and going to the next one.

For example, I'm on question 6. The screen gets rotated, it goes to question 1 again but if I were to answer question 1, the next question that appears is question 8. Each screen rotation is counting as one question. I'm confused.

List<Question> mQuestionList;
int score = 0;
int qid = 0;
Question currentQ;
TextView txtQuestion, times, scored;
Button button1, button2, button3, button4;
private static final String TAG = "NoTimerQuestion";
private static final String KEY_INDEX = "index";
private static final String KEY_SCORE = "scoreindex";

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



DbHelper db = new DbHelper(this); // my question bank class
mQuestionList = db.getAllQuestions(); // this will fetch all questions
currentQ = mQuestionList.get(qid); // the current question
txtQuestion = (TextView) findViewById(R.id.txtQuestion);
times = (TextView) findViewById(R.id.timers);
times.setText("");

button1 = (Button) findViewById(R.id.button1);
button2 = (Button) findViewById(R.id.button2);
button3 = (Button) findViewById(R.id.button3);
button4 = (Button) findViewById(R.id.button4);
scored = (TextView) findViewById(R.id.score);

if(savedInstanceState != null){
qid = savedInstanceState.getInt(KEY_INDEX,0);
score = savedInstanceState.getInt(KEY_SCORE,0);
}

setQuestionView();

button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

getAnswer(button1.getText().toString());
}
});
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getAnswer(button2.getText().toString());
}
});
button3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getAnswer(button3.getText().toString());
}
});
button4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getAnswer(button4.getText().toString());
}
});
}
public void getAnswer(String AnswerString) {
if (currentQ.getANSWER().equals(AnswerString)) {
score++;
scored.setText("Score : " + score);
}
if (++qid < 20) {
currentQ = mQuestionList.get(qid);
setQuestionView();
} else {
Intent intent = new Intent(NoTimerQuestion.this,
ResultsActivity.class);
Bundle b = new Bundle();
b.putInt("score", score); // Your score
intent.putExtras(b); // Put your score to your next
startActivity(intent);
finish();
}
}

private void setQuestionView() {
txtQuestion.setText(currentQ.getQUESTION());
button1.setText(currentQ.getOPTA());
button2.setText(currentQ.getOPTB());
button3.setText(currentQ.getOPTC());
button4.setText(currentQ.getOPTD());
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState){
super.onSaveInstanceState(savedInstanceState);
Log.i(TAG, "onSaveInstanceState");
savedInstanceState.putInt(KEY_INDEX, qid);
savedInstanceState.putInt(KEY_SCORE, score);
}
}

Answer

You need to restore the qid before loading the question using mQuestionList.get(qid), otherwise the question will always be the first one as qid hasn't been restored yet.

Put it directly after setting the content view, for example (inside onCreate):

setContentView(/*...*/);
if (savedInstanceState != null){
    qid = savedInstanceState.getInt(KEY_INDEX,0);
}
// Now load your question with the qid
currentQ = mQuestionList.get(qid);

Also, in order to have the correct qid you need to either subtract 1 when restoring the qid or only increment it when you're actually loading a new question:

public void getAnswer(String AnswerString) {
    // ...
    if (++qid < 20) { // - add increment here
        currentQ = mQuestionList.get(qid);
        setQuestionView();
    } else {
        // ...
    }
}

private void setQuestionView() {
    // ...
    // qid++; - remove increment here
}

See the Logging StackOverflow documentation for instructions on using the logcat for debugging.