One of the more frustrating things about creating Android layouts is being able to gracefully handle screen rotation. By default, there is only one layout folder created for you, called layout. Unless you specify otherwise, the layout that you assign in the app's onCreate() method (e.g. setContentView(R.layout.main)
), will apply in both screen orientations. However, most apps use a different layout based on the screen orientation.
There are a couple of ways to accomplish this:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
setContentView(R.layout.landscapeLayoutFile);
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
setContentView(R.layout.portraitLayoutFile);
}
}
android:configChanges="keyboardHidden|orientation"
Generally speaking, both options give the same end result. However, option 2 is more succinct, and it allows the SDK to do a lot of the work for us....so we'll use option 2.
At this point, you've probably made the mental note that there may be Views in your landscape layout that do not exist in the portrait version (for example, in Assignment 1, the landscape calulator interface has many nore buttons). Why does this matter? Let’s say for example that in your onCreate() method, you put in all the code to create references to every button, including those that are exclusive to the landscape View. You start up your app to test it and it crashes. Why?
Well, when your app starts, it will initially load the portrait layout (assuming the device is in portrait mode to start):
setContentView(R.layout.portraitLayoutFile);
Since the portrait layout file does not contain some of the Views you’ve created references to in onCreate(), it will fail to find them…and the app will crash miserably.
How can you prevent this? There are a few solutions, but I’ll give you two. Both solutions take into account our main problem: that some of the buttons in our app only exist in the landscape layout file. So it makes sense that you only reference the landscape-only buttons when in landscape mode:
try {
Button button1 = (Button) findViewById(R.id.button1);
.
.
button1.setOnClickListener(this);
} catch (Exception e) {
Log.e(TAG, “Can only create these Views in landscape mode”);
}
getResources().getConfiguration().orientation
if (getResources().getConfiguration().orientation
== Configuration.ORIENTATION_LANDSCAPE) {
Button button1 = (Button) findViewById(R.id.button1);
.
.
button1.setOnClickListener(this);
}