Your app works great on phones in portrait orientation, so you've restricted the app to portrait only. But you see an opportunity to do more on large screens in landscape orientation.
How can you have it both ways—restrict the app to portrait orientation on small screens, but enable landscape on large?
Best practices
The best apps respect user preferences such as device orientation.
The Adaptive app quality guidelines recommend that apps support all device configurations, including portrait and landscape orientations, multi-window mode, and folded and unfolded states of foldable devices. Apps should optimize layouts and user interfaces for different configurations, and apps should save and restore state during configuration changes.
This recipe is a temporary measure—a pinch of large screen support. Use the recipe until you can improve your app to provide full support for all device configurations.
Ingredients
screenOrientation: App manifest setting that enables you to specify how your app responds to device orientation changesActivity#setRequestedOrientation(): Method with which you can change the app orientation at runtimeLocalConfiguration: Composable local provider that exposes the current deviceConfiguration, allowing you to read screen dimensions in DPs.LaunchedEffect: Compose side-effect API that runs a block of code when a key changes (in this case, when the configuration changes).
Steps
Enable the app to handle orientation changes by default in the app manifest. Then, at runtime, use Jetpack Compose to dynamically restrict the orientation to portrait on compact screens (phones) while allowing all orientations on large screens.
1. Specify orientation setting in the app manifest
You can either avoid declaring the screenOrientation element of the app
manifest (in which case orientation defaults to unspecified) or set screen
orientation to fullUser. If the user has not locked sensor-based rotation,
your app will support all device orientations.
<activity
android:name=".MyActivity"
android:screenOrientation="fullUser">
The difference between using unspecified and fullUser is subtle but
important. If you don't declare a screenOrientation value, the system chooses
the orientation, and the policy the system uses to define the orientation might
differ from device to device. On the other hand, specifying fullUser matches
more closely the behavior the user defined for the device: if the user has
locked sensor-based rotation, the app follows the user preference; otherwise,
the system allows any of the four possible screen orientations (portrait,
landscape, reverse portrait, or reverse landscape). See
android:screenOrientation.
2. Dynamically restrict orientation in Compose
In Jetpack Compose, you can read the current screen dimensions in DPs reactively
from LocalConfiguration.current and use a LaunchedEffect to update the
Activity's orientation whenever the configuration changes.
If either the screen width or height is less than 600dp (corresponding to the
compact breakpoint for phones), restrict the orientation to portrait. Otherwise,
allow the system to rotate the app based on the user's preference (unspecified
or fullUser).
Here is the complete, compilable implementation:
val configuration = LocalConfiguration.current val context = LocalActivity.current LaunchedEffect(configuration) { val activity = context ?: return@LaunchedEffect // Determine if screen is compact (phone-sized) in either width or height val isCompact = configuration.screenWidthDp < 600 || configuration.screenHeightDp < 600 activity.requestedOrientation = if (isCompact) { ActivityInfo.SCREEN_ORIENTATION_PORTRAIT } else { ActivityInfo.SCREEN_ORIENTATION_FULL_USER } }
By adding the logic inside a LaunchedEffect(configuration) block, you're able
to reactively override the orientation setting whenever the app configuration
changes, such as when the activity is resized, moved between displays, or when a
foldable device is folded or unfolded.
For more information about when configuration changes occur and when they cause activity recreation, refer to Handle configuration changes.
Results
Your app should now remain in portrait orientation on small screens regardless of device rotation. On large screens, the app should support landscape and portrait orientations.
Additional resources
For help with upgrading your app to support all device configurations all the time, see the following: