问题
I am having trouble setting up landscape mode in my application.
I have a /res folder that contains a layout folder and a layout-land folder
layout
-----main.xml
layout-land
-----main.xml
My /layout-land/main.xml contains different UI elements than /layout/main.xml. How can I map each layout appropriately when the user has switched to landscape mode and vice versa?
I am basically displaying a full screen ImageView when the user switches to landscape mode. The ImageView will download an image from the internet and display it. Switching back to portrait, should simply go back to my portrait mode, which has a different set of UI components.
I get a crash when I switch to landscape mode:
because I can't get the id:
chartImageViewLandscape = (ImageView) this.findViewById(R.id.chartImageViewLandscape);
chartImageViewLandscape is in /layout-land/main.xml
How can I get a reference to this?
回答1:
Sheehan, regarding onRetainNonConfigurationInstance(), below is what I am currently doing for my app in progress. I have the feeling I'm overcomplicating it though, I think there's a simpler way; however, this works just fine for me currently:
So in my activity class "RotationMenu.java":
private Object catcher;
//lots of non-related code here
//directoryList is a returned list of selected directories, that I wish to
//retain in the event of an orientation state change.
String[] directoryList = new String[arrayList.size()];
arrayList.toArray(directoryList);
//here, I set the class Object catcher to the directoryList
catcher = directoryList;
//rest of non-related code
//this method is called when the orientation changes (for me,
//when I open my Droid's hardware keyboard)
public Object onRetainNonConfigurationInstance()
{
//If I've entered anything into my catcher Object, it will be kept
//across orientation changes.
final Object data = catcher;
return data;
}
Now, in my onCreate(Bundle savedInstanceState) method:
//We retrieve the stored Object and cast it to a String array
final Object recipient = (String[]) getLastNonConfigurationInstance();
//in case the state changes again before the code that sets the directories is run
catcher = recipient;
//if there was any stored data, we can now reinstate the list adapter where the
//directoryList was originally being used.
if(recipient != null)
{
returnedDirectories.setAdapter(new ArrayAdapter<String>(
this.getBaseContext(),
R.layout.simple_list_item_small,
(String[])recipient));
}
Again, this is how I am doing it currently. If anyone knows of a more efficient method, by all means comment. :)
回答2:
What is the question exactly ?
Do you define the android:orientation
in both of your layouts ? Beside that, nothing else to do. Android will switch by itself.
If you have different UI components, you probably want to still declare them in both layouts so that any call to findViewById
will not crash your app. Just make the layout so that they are not displayed (in a FrameLayout, behind the image for example)
If you prefer to do it more manually, you need to put an android:configChanges="orientation"
in your manifest and implement onConfigurationChanged
回答3:
This is from AdMob activity and has more parameters e.g. screenSize is for Android 3.2+
<activity android:name="com.google.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
回答4:
Go to your Android "manifest" xml file and make sure the following is present in the "Activity" section:
android:configChanges="orientation|screenSize|keyboardHidden"
Your final "activity" section of the manifest should look similar to the following:
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
来源:https://stackoverflow.com/questions/3638467/app-crashes-when-switching-to-landscape-layout