Screen Rotation gives the application error


#1

Hi, I am implementing the screen rotation and have already created layout-land folder in res folder.
Here is my xml for activity_quiz.xml in layout-land:

[code]

<TextView
    android:id="@+id/question_text_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:padding="24dp" />

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal|center_vertical"
    android:orientation="horizontal" >

    <Button
        android:id="@+id/true_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/true_button" />

    <Button
        android:id="@+id/false_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/false_button" />
</LinearLayout>

<Button
    android:id="@+id/next_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/next_button"
    android:drawableRight="@drawable/arrow_right"
    android:drawablePadding="4dp"
    android:layout_gravity="bottom|right"/>

[/code]

However, when I change my device orientation, it closes the app and says: Unfortunately, GeoQuiz has stopped.

What might cause the issue?

Thank you in advance!


#2

Could you post your code for QuizActivity.java? In particular, the methods onCreate and onSaveInstanceState.


#3

[code][color=#00BF00]It happened the same to me and I found that in the book it is used the same id for the ImageButton and the Button Next.

<Button ImageButton
android:id="@+id/next_button"
android:layout_width=“wrap_content"
android:layout_height=“wrap_content"
android:text="@string/next_button"
android:drawableRight="@drawable/arrow_right"
android:drawablePadding="4dp"

android:src=”@drawable/arrow_right”
/>

So when you rotate one of the views are not in the screen so it cannot find the id and it returns null the findViewById.

Here is my code that it’s working now:

package gomez.julio.geoquiz;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

public class QuizActivity extends ActionBarActivity {
private static final String TAG = “QuizActivity”;
private Button mTrueButton;
private Button mFalseButton;
private Button mNextButton;
private ImageButton mNextImageButton;
private ImageButton mBackImageButton;
private TextView mQuestionTextView;
private TrueFalse[] mQuestionBank = new TrueFalse[]{
new TrueFalse(R.string.pregunta_oceano, true),
new TrueFalse(R.string.pregunta_medoriente, false),
new TrueFalse(R.string.pregunta_africa, false),
new TrueFalse(R.string.pregunta_americas, true),
new TrueFalse(R.string.pregunta_asia, false),
};
private static int mCurrentIndex = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	Log.d(TAG, "onCreate(Bundle) called");
	setContentView(R.layout.activity_quiz);
	mQuestionTextView = (TextView) findViewById(R.id.question_text_view);
	mNextImageButton = (ImageButton) findViewById(R.id.next_imagebutton);
	mNextButton = (Button) findViewById(R.id.next_button);
	mBackImageButton = (ImageButton) findViewById(R.id.back_imagebutton);
	
	if( mNextImageButton != null )
	mNextImageButton.setOnClickListener(new View.OnClickListener() {
		
		@Override
		public void onClick(View v) {
			nextButton();
		}
	});
	
	if( mNextButton != null )
	mNextButton.setOnClickListener(new View.OnClickListener() {
		
		@Override
		public void onClick(View v) {
			nextButton();
			
		}
	});
	
	if( mBackImageButton != null )
	mBackImageButton.setOnClickListener(new View.OnClickListener() {
		
		@Override
		public void onClick(View v) {
			updateCurrentIndex(-1);
			updateQuestion();
		}
	});
	
	if( mQuestionTextView != null )
	mQuestionTextView.setOnClickListener( new View.OnClickListener(){

		@Override
		public void onClick(View arg0) {
			// TODO Auto-generated method stub
			updateCurrentIndex(+1);
			updateQuestion();
		}			
	});
	
	mTrueButton = (Button) findViewById(R.id.true_button);
	if( mTrueButton != null )
	mTrueButton.setOnClickListener(new View.OnClickListener(){		
		@Override
		public void onClick(View v) {
			checkAnswer(true);
		}
		
	});
	mFalseButton = (Button) findViewById(R.id.false_button);
	if( mFalseButton != null )
	mFalseButton.setOnClickListener(new View.OnClickListener() {
		
		@Override
		public void onClick(View v) {
			checkAnswer(false);
		}
	});

	updateQuestion();
}

private void nextButton(){
	updateCurrentIndex(+1);
	updateQuestion();
}

private void updateCurrentIndex(int i) {
	if( i == - 1 && mCurrentIndex == 0 ) mCurrentIndex = mQuestionBank.length; 
	mCurrentIndex = ( mCurrentIndex + i ) % mQuestionBank.length;
}

private void checkAnswer(boolean userPressedTrue){
	boolean answerIsTrue = mQuestionBank[mCurrentIndex].isTrueQuestion();
	
	int messageResId = 0;
	
	if( userPressedTrue == answerIsTrue ){
		messageResId = R.string.correcto_toast;
	}else{
		messageResId = R.string.incorrecto_toast;
	}
	
	Toast.makeText(this, messageResId, Toast.LENGTH_SHORT).show();
		
}

private void updateQuestion() {	
	
	int question = mQuestionBank[mCurrentIndex].getQuestion();
	mQuestionTextView.setText(question);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
	// Inflate the menu; this adds items to the action bar if it is present.
	getMenuInflater().inflate(R.menu.quiz, menu);
	return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
	// Handle action bar item clicks here. The action bar will
	// automatically handle clicks on the Home/Up button, so long
	// as you specify a parent activity in AndroidManifest.xml.
	int id = item.getItemId();
	if (id == R.id.action_settings) {
		return true;
	}
	return super.onOptionsItemSelected(item);
}

@Override
public void onStart(){
	super.onStart();
		
	Log.d(TAG, "onStart() called");
}

@Override
public void onPause(){
	super.onPause();
		
	Log.d(TAG, "onPause() called");
}

@Override
public void onResume(){
	super.onResume();
		
	Log.d(TAG, "onResume() called");
}

@Override
public void onStop(){
	super.onStop();
		
	Log.d(TAG, "onStop() called");
}

@Override
public void onDestroy(){
	super.onDestroy();
		
	Log.d(TAG, "onDestroy() called");
}

}

[/color][/code]


#4

Thank you, awareness09.
Very good and accurately explained the reason for the error.


#5

Thank you for explanation :slight_smile: I fixed the error as you suggested.


#6

awareness09 … Thanks! Great catch. Great explanation. My console had the NullPointerException filtered out. All good now.