Allow multiple screen orientations
On Android, make sure that the android:screenOrientation attribute is not used anywhere.
Open Android Studio and press the Shift key twice to open the search dialog. Search for android:screenOrientation. In case there are search results, remove the attribute.
You probably need to make additional code adjustments to make sure the all orientations are working as intended.
To listen to orientation changes, add android:configChanges="orientation" to your manifest. Then, override the onConfigurationChanged) to receive configuration notifications. Use the orientation property of the Configuration object to check the new orientation.
xml
<activity
android:name=".ApptActivity"
android:screenOrientation="portrait" <!-- Remove -->
android:configChanges="orientation" <!-- Add -->
</activity> kotlin
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
when (newConfig.orientation) {
Configuration.ORIENTATION_PORTRAIT -> {
// Portrait logic
}
Configuration.ORIENTATION_LANDSCAPE -> {
// Landscape logic
}
else -> {
// Ignored
}
}
} In Jetpack Compose, make sure that the android:screenOrientation attribute is not used anywhere.
Open Android Studio and press the Shift key twice to open the search dialog. Search for android:screenOrientation. In case there are search results, remove the attribute.
You probably need to make additional code adjustments to ensure all orientations work as intended.
There are two main approaches to changing the UI based on orientation in Jetpack Compose.
The first approach is to use the LocalConfiguration object to get the current screen orientation and change the UI based on that.
kotlin
@Composable
fun ConfigChangeExample() {
val configuration = LocalConfiguration.current
when (configuration.orientation) {
Configuration.ORIENTATION_LANDSCAPE -> {
// Landscape logic
}
else -> {
// Portrait logic
}
}
} kotlin
@Composable
fun WindowSizeExample(widthSizeClass: WindowWidthSizeClass) {
when(widthSizeClass) {
WindowWidthSizeClass.Expanded -> // orientation is landscape in most devices including foldables (width 840dp+)
WindowWidthSizeClass.Medium -> // Most tablets are in landscape, larger unfolded inner displays in portrait (width 600dp+)
WindowWidthSizeClass.Compact -> // Most phones in portrait
}
} On iOS, make sure all UIInterfaceOrientationMask values are used for the UISupportedInterfaceOrientations key inside the Info.plist file.
To listen to orientation changes, subscribe to orientationDidChangeNotification. Check the device orientation using UIDevice.current.orientation.
xml
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array> swift
private var subscriptions = Set<AnyCancellable>()
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter
.default
.publisher(for: UIDevice.orientationDidChangeNotification)
.sink { [weak self] _ in
if (UIDevice.current.orientation.isLandscape) {
// Landscape logic
} else {
// Portrait logic
}
}
.store(in: &subscriptions)
} In SwiftUI, make sure all UIInterfaceOrientationMask values are used for the UISupportedInterfaceOrientations key inside the Info.plist file.
To listen to orientation changes, subscribe to orientationDidChangeNotification in the onReceive) method. Check the device orientation using UIDevice.current.orientation.
xml
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array> swift
@State var currentOrientation = UIDevice.current.orientation
private let orientationChangedNotification = NotificationCenter.default
.publisher(for: UIDevice.orientationDidChangeNotification)
.makeConnectable()
.autoconnect()
var body: some View {
OrientationAdaptiveView()
.onReceive(orientationChangedNotification) { _ in
// Reach to device orientation change
self.currentOrientation = UIDevice.current.orientation
}
} With Flutter, multiple screen orientations are enabled by default.
Orientation can be locked by using the setPreferredOrientations method of SystemChrome. Make sure to pass all DeviceOrientation values, or simply remove the code from your app.
By using an OrientationBuilder it is possible to make adjustments based on the orientation of the screen.
dart
// Allow all orientations
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft
]);
// Listen to orientation changes
OrientationBuilder(
builder: (context, orientation) {
return GridView.count(
// Grid with 2 columns in portrait and 3 columns in landscape
crossAxisCount: orientation == Orientation.portrait ? 2 : 3,
);
},
), In React Native, multiple screen orientations are enabled by default. Locking screen orientation is handled in native code:
- For Android, remove instances of the
android:screenOrientationattribute. - For iOS, check if 4 orientations have been added to
UISupportedInterfaceOrientations.
You can use the Dimensions API to listen to orientation changes.
jsx
Dimensions.addEventListener('change', () => {
this.setState({
orientation: Platform.isPortrait() ? 'portrait' : 'landscape'
});
}); In MAUI, there is a simple way to listen for screen orientation changes by subscribing to the DeviceDisplay.Current.MainDisplayInfoChanged handler.
csharp
DeviceDisplay.Current.MainDisplayInfoChanged += (sender, displayChanges) =>
{
var newOrientation = displayChanges.DisplayInfo.Orientation;
//Apply any logic
}; When using Xamarin.Forms, device orientation is set at the project level.
- For Android: open
MainActivity.csand decorate theMainActivityclass with[Activity (ScreenOrientation = ScreenOrientation.FullUser)]. - For iOS: open
Info.plistand check allDevice Orientationcheckboxes.
You can listen to orientation changes by using the DeviceDisplay class included in Xamarin.Essentials.
csharp
public class OrientationChanges
{
public OrientationChanges()
{
// Subscribe to changes of screen metrics
DeviceDisplay.MainDisplayInfoChanged += OnMainDisplayInfoChanged;
}
void OnMainDisplayInfoChanged(object sender, DisplayInfoChangedEventArgs e)
{
// Process changes
var displayInfo = e.DisplayInfo;
}
}