4

I have alternative layouts in my layout-normal-land and layout-normal-port folders and they are correctly invoked by the system according to if I hold the device in land or port at start. My problem is, when I rotate the device AFTER I have launched the app, it tries to somehow adapt the already displayed view to the new situation, creating a mess. How can I tell the system it should switch to the alternate layout during execution?

Have been experimenting around and found that when I dont have android:configChanges="keyboardHidden|orientation" , oncreate gets called again, which gives the correct layout, but its not what I want to have. I dont think this is normal, is it? Maybe a question of bug in Android (2.3.3.)?

michaelsmith
  • 1,011
  • 1
  • 16
  • 35
  • it should automatically switch the xml layout based on the orientation change, but if the device you're testing it on doesn't have a "normal" screen, it'll skip both those layouts. – Bill Gary Feb 03 '12 at 21:42

5 Answers5

12

By including

android:configChanges="orientation"

in your manifest you are saying you want to handle orientation changes yourself. You should remove it if you want the system to handle it for you.

The automatic handling works extremely well. You should only override it if you have a specific reason for doing so.

In normal operation (without the above manifest entry), an orientation switch causes the current activity to be closed and then re-opened in its new orientation reloading all resources and layouts from the currently active resource folders. The process follows what is known as the "Activity Lifecycle".

If you include the above manifest entry, you are saying, "I will handle all changes myself. Do not close my activity" so it is then your responsibility to remove all unwanted layouts from the activity and replace them with the layouts you now require for the current orientation.

Kuffs
  • 35,581
  • 10
  • 79
  • 92
  • 2
    I removed it now, but I get the oncreate called at each device rotation. That's not what I want. What do you suggest? – michaelsmith Feb 06 '12 at 14:24
  • You cannot have it both ways. You either have to let the system handle the orientation change or you handle them yourself. It appears you have not understood the fundamental Android Activity Lifecycle. You should make sure you understand this before attempting anything else.http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle Orientation change closes your activity and re-starts it so the onCreate method is required. The alternative is to manually change your activities layouts for the new size. Not an easy task. – Kuffs Feb 06 '12 at 14:31
  • Am starting to get it. restarting my activity is not an option, so I need to do an onConfigurationChanged. Is it allowed to do a setContentView in that method? I have tried it, but it crashes – michaelsmith Feb 06 '12 at 15:06
  • http://developer.android.com/guide/topics/resources/runtime-changes.html I believe SetContentView can be called only once. If re-starting the activity is "not an option" you probably need to re-think the design of your app as orientation change is not the only time an activity would re-start. e.g receiving a phone call could cause your app to be closed until the call was over. It would not be a good experience for the user if your app could not handle this. – Kuffs Feb 06 '12 at 15:16
  • Well, I'm coming from ios, and receiving a phone call does not restart the app. Bad news! I have a thread running that receives gps location info and it is configured to be able to run in background. would a phone call stop this as well? – michaelsmith Feb 06 '12 at 15:28
  • You should use services for this type of operation and communicate with your services from the activities. If your GPS thread is part of your activity then yes, it could possibly be closed. With a properly written app, the user would be unaware that the activity was re-starting. Refer back to the "Activity Lifecycle" I mentioned earlier. – Kuffs Feb 06 '12 at 15:36
0

I have run into the same problem, and I did not have android:configChanges="orientation" in my manifest.

However I did have [Activity(ConfigurationChanges = ConfigChanges.Orientation)] in my mainactivity. That seemed to be another way to override the automatic orientation handling.

Carlo
  • 1
0

Do you already use an OrientationListener? If no:

http://developer.android.com/reference/android/view/OrientationEventListener.html#onOrientationChanged(int)

the listener should detect orientation changes. Then you call setContentView (R.layout.name_of_layout) in your Activity class.

Hope this helps.

user1178185
  • 13
  • 1
  • 5
0

do you have android:configChanges="orientation" in your manifest on that activity? That will prevent android from automatically changing your layout.

JustinMorris
  • 7,259
  • 3
  • 30
  • 36
  • I have this in my Manifest. I also have the orientationChangeListener and I do a new setContentView, which leads to a crash: "You are only allowed to have a single MapView in MapActivity". I have the correct layout folders in place. And still the same problem... – michaelsmith Feb 04 '12 at 16:05
0

May be obvious, but:

  1. Within the res folder make sure you have the folders labelled "layout" and "layout-land".
  2. Portrait and landscape .xml files must have the same filename.
Odhran
  • 95
  • 5
  • 12
  • I have folders layout (no main.xml) and layout-land and layout-port (both with main.xml). The xml get invoked correctly at launch time, the problem is when I change device orientation during execution – michaelsmith Feb 04 '12 at 16:18