Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

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

Closed
rciovati opened this Issue · 26 comments
@rciovati

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.

@JakeWharton
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?

@JakeWharton
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...

@rciovati

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.

@JakeWharton
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...

@JakeWharton
Owner

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

@rciovati

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.

@rciovati

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.

@ocramedl

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!).

@luciofm

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

@JakeWharton
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.

@iNoles

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

@JakeWharton
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.

@luciofm

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

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.

@atermenji

Is this fixed already?

@tianon

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.

@JakeWharton
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

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

@JakeWharton
Owner

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

@tianon

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

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).

@sabagithub

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

@intrications intrications referenced this issue in ginatrapani/todo.txt-android
Closed

Remove outdated configchanges from AndroidManifest.xml #372

@JakeWharton JakeWharton closed this
@alexzaitsev

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.