Skip to content
This repository

Actionbar changes are not properly handled if activity has android:configChanges="orientation" #279

Closed
rciovati opened this Issue February 16, 2012 · 26 comments
Riccardo Ciovati

I have one activity that has

android:configChanges="orientation"

and in the menu has

android:showAsAction="ifRoom|withText"

The expected behaviour is that when the screen is in portrait i see just the icon and when it is in landscape i see also the text at the right of the action bar icon.
It works on 4.0.3 but Android 2.3.7 when i rotate the screen it doesn't update the action bar icon.

Jake Wharton
Owner

I think I may have fixed this already this morning (but forgot to push). Would you mind grabbing the latest library/ from 4.0-wip and giving it a try?

Jake Wharton
Owner

Here's the SHA of the possible fix: 656419d

edit: On second thought, this would only be for pre-2.2. I'll look into it...

Riccardo Ciovati

It's pretty strange. I just tried it on:

-2.2 emulator: ok
-2.3.3 emulator: ok
-2.3.7 device: not woking

I will take a look more in detail.

Jake Wharton
Owner

Alright there's definitely something wonky going on. I've never dealt with handling config changes before but the emulator behaves differently from real devices. Perhaps it causes a keyboard change on rotation as well or something.

In any case. Now that I've temporarily removed a broken IcsLinearLayout class for the action item display I can see things more clearly. Everything is definitely behaving properly when the callbacks are firing. I just have to determine whether or not they fire as expected.

The documentation for View says that on API 8 and above the entire view hierarchy will receive configuration change callbacks and on anything less than 8 I dispatch them myself through the tree. I'll have to flash 2.3, 2.2 and 2.1 on my Nexus One to try (or figure out how to get the emulator to not recreate on rotation).

If you want, you can grab the library/ from the latest in the 4.0-wip branch and try again to see what you get. Just be careful because anything with animation (e.g., action modes) will force close your app at the moment...

Jake Wharton
Owner

Got it working on the emulator. Needed keyboardHidden apparently...

Riccardo Ciovati

I noticed that the emulator re-create the activity when i rotate the screen, also if i have

android:configChanges="orientation"

so it's normal that it works.

raymanzhang

Don't know what you mean for "get the emulator to not recreate on rotation"(Sorry My English is not good).
If you want to avoid activity recreation on rotation, add android:launchMode="singleTop" and android:configChanges="orientation|keyboardHidden" in AndroidManifest.xml. This works for emulator before ICS.
If you just want to rotate the emulator, press Ctrl-F11.

Riccardo Ciovati

For me doesn't work, but this is not important.
On the device (htc desire with 2.3.7) for avoid activity recreation it's enough

android:configChanges="orientation"

but the problem is that action bar is not properly refreshed.

I'm using ABS on a HTC smartphone device (800x480) with 2.3.7 too and have issues similar to what rciovati described when using:

android:configChanges="orientation"

In particular, if I start my activity in portrait and rotate to landscape, ABS action icons are correctly moved from bottom to top, they also work correctly, but they do not display labels as they should, since I used:

android:showAsAction="ifRoom|withText"

On the contrary, if I start the activity in landscape and rotate to portrait, ABS action icons are correctly moved from top to bottom, but they DO NOT work correctly (they do not react to clicks), and they still display labels as if they where on top.

I know that using the android:configChanges attribute is not recommended, but in some contexts it really comes in handy! (e.g. I have a very complex fragment backstack that I would really not like to save and restore upon screen rotation)

Could you tell us whether/when you are going to fix up such issues?
Alternatively, or in the meantime, do you have any suggestion about how we can (at least temporarily) overcome such issue by making some changes in the ABS library code?
For instance, is it possible to programmatically recreate just the ABS, instead of the whole FragmentActivity when needed? Or is it possible to modify the code to make this possible?

Thanks in advance (and thanks for your great library, of course!).

Lucio Maciel

Hi Jake,

Can you give me some directions on this issue, on where is the problem, and what is your possible solution to it.
Maybe I could take a look on it

Jake Wharton
Owner

I just need to figure out how the platform is able to do this properly with regards to the different view configurations (e.g., split action bar to non-split, stacked tabs to non-stacked) while still maintaining full functionality.

Jonathan

There is View#onConfigurationChanged will be called when you are doing screen rotations.

Jake Wharton
Owner

On 2.2+. On 2.1 I have to dispatch it manually to all who need to receive it. That was already taken care of.

Lucio Maciel

I just experienced an extrange behavior here,

I'm testing on a HTC Desire 2.2, and when using android:configChanges="keyboardHidden|orientation|screenSize" and android:uiOptions="splitActionBarWhenNarrow", when I rotate the device, if I double click and actionbar Tab, when I restore the original orientation, the actionbar finally receives the onTabSelected() on the double touched Tab.

If I click only once in another tab, when restoring to the original orientation, the onTabSelected() is not called.

savascinar

I have same experience. On 2.3.5 , samsung galaxy player 5.0 , and use last version sherlock library.

chris84
chris84 commented May 31, 2012

Is there any workaround or fix for this?
Besides removing the android:configChanges entry?

lindalee

I have this problem too.
Looks like it is resolved since Jelly Bean(Android 4.1.*) .
http://hala01.com/src/android/android-4.1.1_r1/HTML/S/58637.html#L329

setSplitActionBar is called when onConfigurationChanged called, and before 4.1 there was no code dealing with LayoutParam and mActionMenuPresenter(who controls the count of icons?)

Here is my question:
Can I replace setSplitActionBar with JellyBean's code?
My code runs well so far.

Thank you for your time.

Artur Termenji

Is this fixed already?

Tianon Gravi

We are having a similar issue, and we have made one tiny modification to the provided "demos" sample application to reproduce it.

We added android:configChanges="keyboard|keyboardHidden|orientation|screenSize" to the TabNavigation <activity> tag in the manifest.

Once you've got it running with that change, pull up the "Tab Navigation" demo on a phone running 2.3 or lower and rotate your screen. Try clicking any one of the tabs displayed, and they're not clickable. If you change the demo to instead have 10, 20, or 30 tabs (to force a spinner), then the spinner is also not clickable, and has the odd side effect that if you click it and then rotate back, the screen updates and then the spinner contents display in the new orientation on top of everything else.

Jake Wharton
Owner

FYI this may never be fully fixed. Avoid handling configuration changes at all costs.

From the Android documentation on android:configChanges:

Using this attribute should be avoided and used only as a last-resort.

Tianon Gravi

Indeed, however this is the only way (currently) to have an embedded WebView not reload the entire page every time the screen rotates.

Jake Wharton
Owner

Detach the WebView from the window and use non-configuration instance saving to pass across activity restarts.

Tianon Gravi

What if the WebView is inside a fragment that doesn't get the option of onRetainNonConfigurationInstance? Is setRetainInstance the alternative, or does our containing Activity have to keep track of saving all of them?

Tianon Gravi

Sorry for the double post, but mostly for posterity's sake, I can confirm that using setRetainInstance does indeed work, provided that you do not return the WebView object directly during onCreateView, and instead return some kind of container, and then remove the WebView from the container during onDestroyView, keeping the WebView object as a state variable that you then add back during the next onCreateView (which occurs right after rotation, so be careful not to recreate a new WebView if you already have one stored away).

Saba Sanatgar

I've read that detaching the WebView from the window during a configuration change, and re-attaching it when a new activity is created will cause the WebView to leak the old activity from which it was created. The reason is that you can't re-assign the WebView's context, so it's still holding onto the old activity. My source: https://groups.google.com/forum/#!msg/android-developers/cWnxkQ8RLeY/RA1n77EDeR8J

Michael Basil intrications referenced this issue in ginatrapani/todo.txt-android June 25, 2013
Closed

Remove outdated configchanges from AndroidManifest.xml #372

Jake Wharton JakeWharton closed this July 02, 2013
metalexman

Guys I have a workaround. Look at this stackoverflow answer: http://stackoverflow.com/a/20590052/1140997
Perfectly works for tabs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.