How to preview Compose layouts in landscape mode

8.8k Views Asked by At

I'm using Android Studio Bumblebee 2021.1.1 Canary 3 + Compose 1.0-rc02, and there seems to be no easy way to force landscape mode for a preview, which includes using resources (in particular dimensions) from -land/ resource folders.

I know that this behaviour is possible in theory, because using @Preview(device = Devices.AUTOMOTIVE_1024p) will use the correct resource values. However, this is not a viable preview option as the pixel density is off compared to the default preview device. (Even when tweaking the preview width, height and font scale, the icons are still the wrong size.)

I was able to make it so that my UI code detects the landscape orientation using the following wrapper

    val lanscapeConfig = LocalConfiguration.current.apply {
        orientation = Configuration.ORIENTATION_LANDSCAPE
    }
    CompositionLocalProvider(LocalConfiguration provides lanscapeConfig) {
        // actual preview code
    }

However this doesn't fix the aforementioned issue with not getting landscape resources using dimensionResource().

Any ideas?

4

There are 4 best solutions below

2
On BEST ANSWER

Based on the new specs this can be done with:

@Preview(
    showSystemUi = true,
    device = "spec:width=411dp,height=891dp,dpi=420,isRound=false,chinSize=0dp,orientation=landscape"
)
2
On

Update 2024-01-18

This feature has been implemented: Preview your UI with composable previews#Use with different devices. From Javier's answer:

@Preview(
    showSystemUi = true,
    device = "spec:width=411dp,height=891dp,dpi=420,isRound=false,chinSize=0dp,orientation=landscape"
)

Current workaround is to use a separate file for the landscape preview and specify device = Devices.AUTOMOTIVE_1024p, and tweak the height and width (but not the font scale).

But I hope someone can come up with a better approach which works with different device types.

@Preview(device = Devices.AUTOMOTIVE_1024p, widthDp = 720, heightDp = 360)
@Composable
fun PreviewLandscape() {
    PreviewHelper() // common preview code to all modes
}
0
On

You can test multiple screen layouts using @PreviewScreenSizes instead of @Preview.

@PreviewScreenSizes
@Composable
private fun PreviewYourComposeStuff (){ ... }

This annotation provides a variety of different layouts, including landscape and TABLET (which is landscape by default). Below, you can see the codes for landscape and TABLET:

@Preview(name = "Phone - Landscape",
         device = "spec:width = 411dp, height = 891dp, orientation = landscape, dpi = 420",
         showSystemUi = true)


@Preview(name = "Tablet", device = TABLET, showSystemUi = true)

Other interesting previews include PreviewFontScale, PreviewLightDark and PreviewDynamicColors

0
On

Check this piece of code. It gives you an approximate view on 5-inch Device and 10-inch Tablet.

It is not precise and does not include pixel density.

It is always better to test on a real device. Or emulator.

@Preview(name = "5-inch Device Portrait", widthDp = 360, heightDp = 640)
@Composable
fun MainContentBoxPreview5Inch() {
    MainContentBox()
}

@Preview(name = "5-inch Device Landscape", widthDp = 640, heightDp = 360)
@Composable
fun MainContentBoxPreview5InchLand() {
    MainContentBox()
}

@Preview(name = "10-inch Tablet Portrait", widthDp = 600, heightDp = 960)
@Composable
fun MainContentBoxPreview10InchTablet() {
    MainContentBox()
}

@Preview(name = "10-inch Tablet Landscape", widthDp = 960, heightDp = 600)
@Composable
fun MainContentBoxPreview10InchTabletLand() {
    MainContentBox()
}