Поддержка различных размеров экрана с помощью Android Jetpack Compose, а также поддержка складного положения устройства, такого как столешница.

Я хочу поддерживать такие устройства, как телефон, планшеты, складные устройства и телевизор. Будет ли следующий код работать для этой цели?

      class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val windowSize = rememberWindowSizeClass()
            when (windowSize.widthWindowSizeClass) {
                is WindowSizeClass.WindowType.COMPACT -> {
                    CompactActivityUi()
                    /*TODO(reason = "Ui for COMPACT window")*/
                }
                is WindowSizeClass.WindowType.MEDIUM -> {
                    /*TODO(reason = "Ui for Medium window")*/
                }
                else -> {
                    /*TODO(reason = "Ui for EXPANDED window")*/
                }
            }
        }
    }
}

@Composable
fun CompactActivityUi() {
    AppTheme {
        Surface(
            modifier = Modifier.fillMaxSize(),
            color = MaterialTheme.colorScheme.background
        ) {

        }
    }
}

data class WindowSizeClass(
    val widthWindowSizeClass: WindowType,
    val heightWindowSizeClass: WindowType,
    val widthWindowDpSize: Dp,
    val heightWindowDpSize: Dp
) {
    sealed class WindowType {
        object COMPACT : WindowType()
        object MEDIUM : WindowType()
        object EXPANDED : WindowType()
    }
}

@Composable
fun Activity.rememberWindowSizeClass(): WindowSizeClass {
    val configuration = LocalConfiguration.current
    val windowMetrics = remember(configuration) {
        WindowMetricsCalculator.getOrCreate()
            .computeCurrentWindowMetrics(activity = this)
    }
    val windowDpSize = with(LocalDensity.current) {
        windowMetrics.bounds.toComposeRect().size.toDpSize()
    }
    return WindowSizeClass(
        widthWindowSizeClass = when {
            windowDpSize.width < 0.dp -> throw IllegalArgumentException("Dp value cannot be negative")
            windowDpSize.width < 600.dp -> WindowSizeClass.WindowType.COMPACT
            windowDpSize.width < 840.dp -> WindowSizeClass.WindowType.MEDIUM
            else -> WindowSizeClass.WindowType.EXPANDED
        },
        heightWindowSizeClass = when {
            windowDpSize.height < 0.dp -> throw IllegalArgumentException("Dp value cannot be negative")
            windowDpSize.height < 480.dp -> WindowSizeClass.WindowType.COMPACT
            windowDpSize.height < 900.dp -> WindowSizeClass.WindowType.MEDIUM
            else -> WindowSizeClass.WindowType.EXPANDED
        },
        widthWindowDpSize = windowDpSize.width,
        heightWindowDpSize = windowDpSize.height
    )
}

@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    CompactActivityUi()
}

Официальная документация

Официальный образец

Официальное видео

Будет ли этот код работать для складных, особенно складных в положении на столе?

Рекомендуется ли иметь BottomNavigation на телефоне, Nav Rail на планшете и Navigation Drawer или TV?

1 ответ

Код, который вы включили, поможет вам поддерживать устройства разных размеров, но не будет обнаруживать складные позы. Для этого вам нужно использовать библиотеку Jetpack Window Manager для доступа FoldingFeatureинформация ( справка по API ).

В официальном образце Compose Jetcaster есть пример того, как определить настольный/книжный режим (MainActivity, WindowInfoUtil), но также важно отметить, что некоторые складные устройства имеют полностью отдельные экраны (даже плоские). Чтобы поддерживать все виды складных устройств, я бы порекомендовал проверить FoldingFeature.isSeparatingимущество в дополнение к FoldingFeature.state.

Для получения дополнительной информации о складной опоре вы можете ознакомиться с этими документами:

По навигации я не знаком с руководством для ТВ, но для других устройств думаю рекомендации зависят от текущего класса размера окна. BottomNavigation лучше всего подходит для COMPACTширина (большинство телефонов), тогда как NavigationRail лучше подходит для MEDIUMа также EXPANDEDширины (планшеты и большие складные).

Другие вопросы по тегам