Thursday, December 4, 2025

Android java: improving application screen form factor

In AndroidManifest.xml we can define screen form factor to used.

These are the options

  1. "unspecified" : The default value. The system chooses the orientation. The policy it uses, and therefore the choices made in specific contexts, might differ from device to device.
  2. "behind" : The same orientation as the activity that's immediately beneath it in the activity stack.
  3. "landscape" : Landscape orientation (the display is wider than it is tall).
  4. "portrait" : Portrait orientation (the display is taller than it is wide).
  5. "reverseLandscape" : Landscape orientation in the opposite direction from normal landscape. Added in API level 9.
  6. "reversePortrait" : Portrait orientation in the opposite direction from normal portrait. Added in API level 9.
  7. "sensorLandscape" : Landscape orientation, but can be either normal or reverse landscape based on the device sensor. The sensor is used even if the user has locked sensor-based rotation. Added in API level 9.
  8. "sensorPortrait" : Portrait orientation, but can be either normal or reverse portrait based on the device sensor. The sensor is used even if the user has locked sensor-based rotation. However, depending on the device configuration, upside-down rotation might not be allowed. Added in API level 9.
  9. "userLandscape" : Landscape orientation, but can be either normal or reverse landscape based on the device sensor and the user's preference. Added in API level 18.
  10. "userPortrait" : Portrait orientation, but can be either normal or reverse portrait based on the device sensor and the user's preference. However, depending on the device configuration, upside-down rotation might not be allowed. Added in API level 18.
  11. "sensor" : The device orientation sensor determines the orientation. The orientation of the display depends on how the user is holding the device. It changes when the user rotates the device. Some devices, though, don't rotate to all four possible orientations, by default. To use all four orientations, use "fullSensor". The sensor is used even if the user locked sensor-based rotation.
  12. "fullSensor" : The device orientation sensor determines the orientation for any of the four orientations. This is similar to "sensor", except this allows for any of the four possible screen orientations regardless of what the device normally supports. For example, some devices don't normally use reverse portrait or reverse landscape, but this enables those orientations. Added in API level 9.
  13. "nosensor" : The orientation is determined without reference to a physical orientation sensor. The sensor is ignored, so the display doesn't rotate based on how the user moves the device.
  14. "user" : The user's current preferred orientation.
  15. "fullUser" : If the user has locked sensor-based rotation, this behaves the same as user, otherwise it behaves the same as fullSensor and allows any of the four possible screen orientations. Added in API level 18.
  16. "locked" : Locks the orientation to its current rotation, whatever that is. Added in API level 18. 

Warning: To improve the layout of apps on form factors with smallest width >= 600dp, the system ignores the following values of this attribute for apps that target Android 16 (API level 36):

  1.     portrait
  2.     landscape
  3.     reversePortrait
  4.     reverseLandscape
  5.     sensorPortrait
  6.     sensorLandscape
  7.     userPortrait
  8.     userLandscape 

To create variant for table,  Goto main activity, on your main activity dropdown select "create table qualifier", it will create copy of main activity that require to modify to match tablet out. the layout is on layout -> main_activity -> main_activity.xml (sw600dp).

In case you want to lock phone to use portrait, delete main_activity.xml (land), you need to remove android:screenOrientation from AndroidManifest.xml. To make it consistent, this is sample of code in java for your main activity

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // 1. Enable edge-to-edge for Java Activities
        // You need to import androidx.activity.EdgeToEdge;
        EdgeToEdge.enable(this);
        super.onCreate(savedInstanceState);
        // Fragment
        // layout portrait or lanscape?
        // portrait my_fragment_container
        // langsacpe fragment_config_container, fragment_main_container
        setContentView(R.layout.activity_m); // general, let system choose between portrait and landscape
        // Check if landscape (two-pane) layout is active
        View config = findViewById(R.id.fragment_config_container);
        View main = findViewById(R.id.fragment_main_container);
        isTwoPane = (config != null && main != null); // already checked not null
        // Conditional Orientation Lock
        if (!isTwoPane) {
            // If single-pane (phone), force portrait before fragment transactions
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        }
        if (isTwoPane) {
            // dual-pane
            setFragment(R.id.fragment_config_container, new FragmentConfig());
            setFragment(R.id.fragment_main_container, new FragmentMain());
        } else {
            // single-pane
            // all phone must use this activity_m.xml (land)
            setFragment(R.id.my_fragment_container, new FragmentMain());
        } 

Immediately, lock screen for single pane (phone) to portrait, i.e. setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);