Reputation: 55714
I'm trying to find a way to properly handle setting up an activity where its orientation is determined from data in the intent that launched it. This is for a game where the user can choose levels, some of which are int portrait orientation and some are landscape orientation. The problem I'm facing is that setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
doesn't take effect until the activity is fully loaded. This is a problem for me because I do some loading and image processing during startup, which I'd like to only have to do once.
Currently, if the user chose a landscape level:
Is there a way to avoid that and have it not perform the loading twice? For example, ideally, the activity would know before even onCreate was called whether it should be landscape or portrait depending on some property of the launching intent, but unless I've missed something that isn't possible. I've managed to hack together a way to avoid repeating the loading by checking a boolean
before the time-consuming loading steps, but that doesn't seem like the right way of doing it. I imagine I could override onSaveInstanceState
, but that would require a lot of additional coding. Is there a simple way to do this?
Thanks!
Solution:
As per Daniel's answer, this was actually quite easy to fix. I just needed to make a few small changes. In my 'menu' Activity, where the player would choose which level to play, I just had to add an if/else check to choose which class would be started by my Intent. This was done with a simple int representing portrait or landscape, determined when the player selected a level. I then created a second class extending my 'GameLogic' class; this is the class which contained most of the code for the game itself, rather than the menus, instructions, etc.
public class GameLandscape extends GameLogic{
}
Literally that simple and completely empty. That way it inherited all the code from my previous activity where I had already coded it to handle things differently depending on the orientation. Lastly I just had to add a line to the manifest stating that GameLandscape would always run in landscape, and GameLogic would always run in portrait.
So a simple problem indeed.
Upvotes: 4
Views: 2849
Reputation: 25058
You could also override onRetainNonConfigurationInstance()
. This lets you temporarily store one item that you can retrieve by calling getLastNonConfigurationInstance()
. That way you can load all of the stuff that you need and in your onRetainNonConfigurationInstance()
method you can save it all into a data structure and return it. The in your onCreate()
you can call getLastNonConfigurationInstance()
and if that returns null load, load all of your stuff, if it return something, then you have it all loaded. Here's a quick example:
public class MyActivity extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
DataStructure myData = (DataStructure)getLastNonConfigurationInstance();
if(myData == null)
{
// Load everything in
}
else
{
// Unpack myData
}
}
@Override
public Object onRetainNonConfigurationInstance()
{
DataStructure myData = new DataStructure();
// Put everything in to myData
return myData;
}
}
Upvotes: 2
Reputation: 87430
You could make two Activities - one for portrait levels, the other for landscape levels - and then set the Activity's orientation in AndroidManifest.xml, using the android:screenOrientation
attribute. You won't even have to duplicate code if you use inheritance; use your current Activity as the base activity, and just create the landscape/portrait Activities as subclasses of that Activity.
I think a better solution would be for the Intent to open the correct Activity of these two, though if you must have everything be routed via Intent extra analysis, you could forward all levels to a third Activity that does nothing more than analyse the Intent and then forward it to the proper Activity.
Upvotes: 6