views:

164

answers:

3

Hi!

I need to apply different layouts for portrait and landscape orientations of my activity. Besides, I need to show alert if orientation is portrait.

I have specified android:configChanges="orientation|keyboardHidden" in AndroidManifest. I also override onConfigurationChanged method like this:

@Override
public void onConfigurationChanged(Configuration newConfig)
{
    Log.d("tag", "config changed");
    super.onConfigurationChanged(newConfig);

    int orientation = newConfig.orientation;
    if (orientation == Configuration.ORIENTATION_PORTRAIT)
        Log.d("tag", "Portrait");
    else if (orientation == Configuration.ORIENTATION_LANDSCAPE)
        Log.d("tag", "Landscape");
    else
        Log.w("tag", "other: " + orientation);

    ....
}

While rotating from landscape to portrait log looks like:

config changed
Portrait

But while changing from portrait to landscape it looks like

config changed
Portrait
config changed
Landscape

Why onConfigurationChanged is called twice? How can I avoid it?

A: 

Is there any particular reason you chose to handle rotation in this manner? While it is quicker since the activity doesn't get restarted on an orientation change, it isn't typically recommended, if I recall correctly. Another way to handle orientation changes is instead of overriding onConfigurationChanged(), overriding onCreate(), onStart() or onResume() such that

@Override
public void onStart() {
    super.onStart();
    int orientation = getWindowManager().getDefaultDisplay().getOrientation();
    if(orientation == Configuration.ORIENTATION_PORTRAIT) {
        Log.i(TAG, "Orientation is portrait");
        // show whatever alerts here
    }
}

and then specifying two layouts - one for portrait, one for landscape. The portrait version of the layout would remain at res/layout/whatever.xml, and the landscape version would live in res/layout-land/whatever.xml. The AndroidGuys had written a bunch of good articles on this topic, see http://androidguys.com/?s=rotational+forces&x=9&y=9

cfei
Why onConfigurationChanged() is bad way? Could you please give me a link with explanation?If I will use onCreate() or something like that the activity will be recreated and its data will be lost.
darja
A: 

I'm pretty sure you would want to use onCreate rather than onStart. The only difference appears to be that onStart will get called when the application comes to the foreground. That wouldn't be a case where you'd want to make the user wait for you to re-initialize the UI. Otherwise, just change your setContentView call based on that if condition.

JOTN
I agree with you, the onCreate method is invoked when the orientation of the device changes
Mina Samy
Why is it better then onConfigurationChanged?
darja
I believe you'll end up building your UI twice in that case. Both onConfigurationChange and onCreate will get called when the screen rotates. You already have to setup the UI in onCreate for all other create situations.
JOTN
I have noticed that if onConfigurationChanged is handled, activity doesn't recreate, onDestroy and onCreate are not called
darja
A: 

Android starts a new instance of your activity when changing orientation so using onCreate is the ideal method. You will have to save/restore your activity's data obviously in order to pick up where you left off - but you should be doing this anyway since any number of events can unfocus/kill your application.

methodin