In case this is of use to some newer dev's because its not specified above. Just to be very explicit:
You need two things if using onConfigurationChanged:
An onConfigurationChanged
method in your Activity Class
Specify in your manifest which configuration changes will be handled by your onConfigurationChanged
method
The manifest snippet in the above answers, while no doubt correct for the particular app that manifest belongs to, is NOT exactly what you need to add in your manifest to trigger the onConfigurationChanged method in your Activity Class. i.e. the below manifest entry may not be correct for your app.
<activity name= ".MainActivity" android:configChanges="orientation|screenSize"/>
In the above manifest entry, there are various Android actions for android:configChanges=""
which can trigger the onCreate in your Activity lifecycle.
This is very important - The ones NOT Specified in the manifest are the ones that trigger your onCreate and The ones specified in the manifest are the ones that trigger your onConfigurationChanged
method in your Activity Class.
So you need to identify which config changes you need to handle yourself. For the Android Encyclopedically Challenged like me, I used the quick hints pop-out in Android Studio and added in almost every possible configuration option. Listing all of these basically said that I would handle everything and onCreate will never be called due to configurations.
<activity name= ".MainActivity" android:configChanges="screenLayout|touchscreen|mnc|mcc|density|uiMode|fontScale|orientation|keyboard|layoutDirection|locale|navigation|smallestScreenSize|keyboardHidden|colorMode|screenSize"/>
Now obviously I don't want to handle everything, so I began eliminating the above options one at a time. Re-building and testing my app after each removal.
Another important point: If there is just one configuration option being handled automatically that triggers your onCreate (You do not have it listed in your manifest above), then it will appear like onConfigurationChanged
is not working. You must put all relevant ones into your manifest.
I ended up with 3 that were triggering onCreate originally, then I tested on an S10+ and I was still getting the onCreate, so I had to do my elimination exercise again and I also needed the |screenSize
. So test on a selection of platforms.
<activity name= ".MainActivity" android:configChanges="screenLayout|uiMode|orientation|screenSize"/>
So my suggestion, although I'm sure someone can poke holes in this:
Add your onConfigurationChanged
method in your Activity Class with a TOAST or LOG so you can see when its working.
Add all possible configuration options to your manifest.
Confirm your onConfigurationChanged
method is working by testing your app.
Remove each config option from your manifest file one at a time, testing your app after each.
Test on as large a variety of devices as possible.
Do not copy/paste my snippet above to your manifest file. Android updates change the list, so use the pop-out Android Studio hints to make sure you get them all.
I hope this saves someone some time.
My onConfigurationChanged
method just for info below. onConfigurationChanged
is called in the lifecycle after the new orientation is available, but before the UI has been recreated. Hence my first if
to check the orientation works correctly, and then the 2nd nested if
to look at the visibility of my UI ImageView also works correctly.
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
pokerCardLarge = findViewById(R.id.pokerCardLgImageView);
if(pokerCardLarge.getVisibility() == pokerCardLarge.VISIBLE){
Bitmap image = ((BitmapDrawable)pokerCardLarge.getDrawable()).getBitmap();
pokerCardLarge.setVisibility(pokerCardLarge.VISIBLE);
pokerCardLarge.setImageBitmap(image);
}
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
pokerCardLarge = findViewById(R.id.pokerCardLgImageView);
if(pokerCardLarge.getVisibility() == pokerCardLarge.VISIBLE){
Bitmap image = ((BitmapDrawable)pokerCardLarge.getDrawable()).getBitmap();
pokerCardLarge.setVisibility(pokerCardLarge.VISIBLE);
pokerCardLarge.setImageBitmap(image);
}
}
}