Use JWM WindowSizeClass in WindowState (#51)
* Update JWM version * Remove custom WindowSizeClass implementation * Update default width/height value to be greater than 0 * Add new window size class tests * Update dependencies * Bump version and update readme
This commit is contained in:
Родитель
8c8f972394
Коммит
613ae1ecfe
|
@ -24,7 +24,7 @@ And the window size classes are measured based on Google's [Window size classes]
|
||||||
2. Add dependencies to the module-level **build.gradle** file (current version may be different from what's shown here).
|
2. Add dependencies to the module-level **build.gradle** file (current version may be different from what's shown here).
|
||||||
|
|
||||||
```gradle
|
```gradle
|
||||||
implementation "com.microsoft.device.dualscreen:windowstate:1.0.0-alpha06"
|
implementation "com.microsoft.device.dualscreen:windowstate:1.0.0-alpha07"
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Also ensure the compileSdkVersion is set to API 33 and the targetSdkVersion is set to API 32 or newer in the module-level build.gradle file.
|
3. Also ensure the compileSdkVersion is set to API 33 and the targetSdkVersion is set to API 32 or newer in the module-level build.gradle file.
|
||||||
|
@ -160,14 +160,14 @@ Check if the device window is in the single landscape posture, with which the de
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
@Composable
|
@Composable
|
||||||
fun widthSizeClass(): WindowSizeClass
|
fun widthSizeClass(): WindowWidthSizeClass
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns the width window size class: **Compact**, **Medium**, **Expanded**, based on the width of the window.
|
Returns the width window size class: **Compact**, **Medium**, **Expanded**, based on the width of the window.
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
@Composable
|
@Composable
|
||||||
fun heightSizeClass(): WindowSizeClass
|
fun heightSizeClass(): WindowHeightSizeClass
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns the height window size class: **Compact**, **Medium**, **Expanded**, based on the height of the window.
|
Returns the height window size class: **Compact**, **Medium**, **Expanded**, based on the height of the window.
|
||||||
|
@ -221,13 +221,13 @@ Returns whether a fold occludes content in the window.
|
||||||
Based on the [occlusionType](https://developer.android.com/reference/androidx/window/layout/FoldingFeature#occlusionType()) field in [FoldingFeature](https://developer.android.com/reference/androidx/window/layout/FoldingFeature).
|
Based on the [occlusionType](https://developer.android.com/reference/androidx/window/layout/FoldingFeature#occlusionType()) field in [FoldingFeature](https://developer.android.com/reference/androidx/window/layout/FoldingFeature).
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
val windowWidthDp: Dp = 0.dp
|
val windowWidthDp: Dp = 1.dp
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns the window width in Dp.
|
Returns the window width in Dp.
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
val windowHeightDp: Dp = 0.dp
|
val windowHeightDp: Dp = 1.dp
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns the window height in Dp.
|
Returns the window height in Dp.
|
||||||
|
|
|
@ -14,11 +14,11 @@ ext {
|
||||||
|
|
||||||
// WindowState library version code:
|
// WindowState library version code:
|
||||||
// If you want to publish a new version, bump in one (1) the specific line(s)
|
// If you want to publish a new version, bump in one (1) the specific line(s)
|
||||||
windowStateVersionCode = 6
|
windowStateVersionCode = 7
|
||||||
|
|
||||||
// WindowState library version name:
|
// WindowState library version name:
|
||||||
// If you want to publish a new version, bump the specific line
|
// If you want to publish a new version, bump the specific line
|
||||||
windowStateVersionName = '1.0.0-alpha06'
|
windowStateVersionName = '1.0.0-alpha07'
|
||||||
|
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
|
|
||||||
|
@ -46,15 +46,16 @@ ext {
|
||||||
// AndroidX dependencies
|
// AndroidX dependencies
|
||||||
appCompatVersion = '1.5.1'
|
appCompatVersion = '1.5.1'
|
||||||
ktxCoreVersion = '1.9.0'
|
ktxCoreVersion = '1.9.0'
|
||||||
windowVersion = "1.0.0"
|
windowVersion = "1.1.0-alpha04"
|
||||||
androidxDependencies = [
|
androidxDependencies = [
|
||||||
appCompat : "androidx.appcompat:appcompat:$appCompatVersion",
|
appCompat : "androidx.appcompat:appcompat:$appCompatVersion",
|
||||||
ktxCore : "androidx.core:core-ktx:$ktxCoreVersion",
|
ktxCore : "androidx.core:core-ktx:$ktxCoreVersion",
|
||||||
window : "androidx.window:window:$windowVersion"
|
window : "androidx.window:window:$windowVersion",
|
||||||
|
windowCore : "androidx.window:window-core:$windowVersion"
|
||||||
]
|
]
|
||||||
|
|
||||||
// Compose dependencies
|
// Compose dependencies
|
||||||
composeVersion = "1.3.0"
|
composeVersion = "1.3.1"
|
||||||
composeCompilerVersion = "1.3.2"
|
composeCompilerVersion = "1.3.2"
|
||||||
activityComposeVersion = '1.6.1'
|
activityComposeVersion = '1.6.1'
|
||||||
navigationComposeVersion = "2.5.3"
|
navigationComposeVersion = "2.5.3"
|
||||||
|
@ -68,15 +69,16 @@ ext {
|
||||||
]
|
]
|
||||||
|
|
||||||
// Test dependencies
|
// Test dependencies
|
||||||
androidxTestVersion = '1.4.0'
|
androidxTestVersion = '1.5.0'
|
||||||
espressoVersion = "3.4.0"
|
androidxTestRunnerVersion = '1.5.1'
|
||||||
|
espressoVersion = "3.5.0"
|
||||||
junitVersion = '4.13.2'
|
junitVersion = '4.13.2'
|
||||||
mockitoVersion = '4.8.1'
|
mockitoVersion = '4.9.0'
|
||||||
uiAutomatorVersion = "2.2.0"
|
uiAutomatorVersion = "2.2.0"
|
||||||
testDependencies = [
|
testDependencies = [
|
||||||
androidxTestCore : "androidx.test:core:$androidxTestVersion",
|
androidxTestCore : "androidx.test:core:$androidxTestVersion",
|
||||||
androidxTestRules : "androidx.test:rules:$androidxTestVersion",
|
androidxTestRules : "androidx.test:rules:$androidxTestVersion",
|
||||||
androidxTestRunner : "androidx.test:runner:$androidxTestVersion",
|
androidxTestRunner : "androidx.test:runner:$androidxTestRunnerVersion",
|
||||||
composeUITest : "androidx.compose.ui:ui-test:$composeVersion",
|
composeUITest : "androidx.compose.ui:ui-test:$composeVersion",
|
||||||
composeJunit : "androidx.compose.ui:ui-test-junit4:$composeVersion",
|
composeJunit : "androidx.compose.ui:ui-test-junit4:$composeVersion",
|
||||||
composeUITestManifest : "androidx.compose.ui:ui-test-manifest:$composeVersion",
|
composeUITestManifest : "androidx.compose.ui:ui-test-manifest:$composeVersion",
|
||||||
|
|
|
@ -67,6 +67,7 @@ dependencies {
|
||||||
implementation androidxDependencies.ktxCore
|
implementation androidxDependencies.ktxCore
|
||||||
implementation androidxDependencies.appCompat
|
implementation androidxDependencies.appCompat
|
||||||
implementation androidxDependencies.window
|
implementation androidxDependencies.window
|
||||||
|
implementation androidxDependencies.windowCore
|
||||||
|
|
||||||
implementation composeDependencies.composeUI
|
implementation composeDependencies.composeUI
|
||||||
implementation composeDependencies.composeRuntime
|
implementation composeDependencies.composeRuntime
|
||||||
|
|
|
@ -11,6 +11,8 @@ import androidx.compose.ui.unit.LayoutDirection
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.height
|
import androidx.compose.ui.unit.height
|
||||||
import androidx.compose.ui.unit.width
|
import androidx.compose.ui.unit.width
|
||||||
|
import androidx.window.core.layout.WindowHeightSizeClass
|
||||||
|
import androidx.window.core.layout.WindowWidthSizeClass
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
@ -98,8 +100,8 @@ class WindowStateTest {
|
||||||
assertEquals(FoldState.FLAT, windowState.foldState)
|
assertEquals(FoldState.FLAT, windowState.foldState)
|
||||||
assertEquals(false, windowState.foldIsSeparating)
|
assertEquals(false, windowState.foldIsSeparating)
|
||||||
assertEquals(false, windowState.foldIsOccluding)
|
assertEquals(false, windowState.foldIsOccluding)
|
||||||
assertEquals(0.dp, windowState.windowWidthDp)
|
assertEquals(1.dp, windowState.windowWidthDp)
|
||||||
assertEquals(0.dp, windowState.windowHeightDp)
|
assertEquals(1.dp, windowState.windowHeightDp)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -357,4 +359,37 @@ class WindowStateTest {
|
||||||
windowState.largeScreenPane1Weight = 0.7f
|
windowState.largeScreenPane1Weight = 0.7f
|
||||||
assertEquals(0.7f, windowState.largeScreenPane1Weight)
|
assertEquals(0.7f, windowState.largeScreenPane1Weight)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* windowSizeClass tests
|
||||||
|
* -------------------------------
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
fun compact_window_size_class() {
|
||||||
|
// Compact width
|
||||||
|
assertEquals(WindowWidthSizeClass.COMPACT, noFoldCompact.widthSizeClass())
|
||||||
|
|
||||||
|
// Compact height
|
||||||
|
assertEquals(WindowHeightSizeClass.COMPACT, noFoldCompact.heightSizeClass())
|
||||||
|
assertEquals(WindowHeightSizeClass.COMPACT, noFoldMediumWidthCompactHeight.heightSizeClass())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun medium_window_size_class() {
|
||||||
|
// Medium width
|
||||||
|
assertEquals(WindowWidthSizeClass.MEDIUM, noFoldMediumWidthMediumHeight.widthSizeClass())
|
||||||
|
|
||||||
|
// Medium height
|
||||||
|
assertEquals(WindowHeightSizeClass.MEDIUM, noFoldMediumWidthMediumHeight.heightSizeClass())
|
||||||
|
assertEquals(WindowHeightSizeClass.MEDIUM, noFoldExpandedWidthMediumHeight.heightSizeClass())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun expanded_window_size_class() {
|
||||||
|
// Expanded width
|
||||||
|
assertEquals(WindowWidthSizeClass.EXPANDED, noFoldExpandedWidthMediumHeight.widthSizeClass())
|
||||||
|
|
||||||
|
// Expanded height
|
||||||
|
assertEquals(WindowHeightSizeClass.EXPANDED, noFoldLargeScreen.heightSizeClass())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the MIT License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.microsoft.device.dualscreen.windowstate
|
|
||||||
|
|
||||||
import androidx.compose.ui.unit.Dp
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
|
|
||||||
enum class WindowSizeClass { COMPACT, MEDIUM, EXPANDED }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates size class for a given dimension
|
|
||||||
*
|
|
||||||
* @param dimenDp: size of dimension in Dp
|
|
||||||
* @param dimen: which dimension is being measured (width or height)
|
|
||||||
*/
|
|
||||||
fun getWindowSizeClass(dimenDp: Dp, dimen: Dimension = Dimension.WIDTH): WindowSizeClass =
|
|
||||||
when (dimen) {
|
|
||||||
Dimension.WIDTH -> getSizeClass(dimenDp, 600.dp, 840.dp)
|
|
||||||
Dimension.HEIGHT -> getSizeClass(dimenDp, 480.dp, 900.dp)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getSizeClass(size: Dp, medium: Dp, expanded: Dp): WindowSizeClass = when {
|
|
||||||
size < 0.dp -> throw IllegalArgumentException("Dp value cannot be negative")
|
|
||||||
size < medium -> WindowSizeClass.COMPACT
|
|
||||||
size < expanded -> WindowSizeClass.MEDIUM
|
|
||||||
else -> WindowSizeClass.EXPANDED
|
|
||||||
}
|
|
|
@ -17,6 +17,9 @@ import androidx.compose.ui.unit.LayoutDirection
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.height
|
import androidx.compose.ui.unit.height
|
||||||
import androidx.compose.ui.unit.width
|
import androidx.compose.ui.unit.width
|
||||||
|
import androidx.window.core.layout.WindowHeightSizeClass
|
||||||
|
import androidx.window.core.layout.WindowSizeClass
|
||||||
|
import androidx.window.core.layout.WindowWidthSizeClass
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data class that contains foldable and large screen information extracted from the Jetpack
|
* Data class that contains foldable and large screen information extracted from the Jetpack
|
||||||
|
@ -38,8 +41,8 @@ data class WindowState(
|
||||||
val foldState: FoldState = FoldState.FLAT,
|
val foldState: FoldState = FoldState.FLAT,
|
||||||
val foldIsSeparating: Boolean = false,
|
val foldIsSeparating: Boolean = false,
|
||||||
val foldIsOccluding: Boolean = false,
|
val foldIsOccluding: Boolean = false,
|
||||||
val windowWidthDp: Dp = 0.dp,
|
val windowWidthDp: Dp = 1.dp,
|
||||||
val windowHeightDp: Dp = 0.dp,
|
val windowHeightDp: Dp = 1.dp,
|
||||||
) {
|
) {
|
||||||
/**
|
/**
|
||||||
* Dp value of the width of the hinge or the folding line if it is separating, otherwise 0
|
* Dp value of the width of the hinge or the folding line if it is separating, otherwise 0
|
||||||
|
@ -143,13 +146,16 @@ data class WindowState(
|
||||||
return windowMode == WindowMode.SINGLE_LANDSCAPE
|
return windowMode == WindowMode.SINGLE_LANDSCAPE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val windowSizeClass
|
||||||
|
get() = WindowSizeClass.compute(dpWidth = windowWidthDp.value, dpHeight = windowHeightDp.value)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the size class (compact, medium, or expanded) for the window width
|
* Returns the size class (compact, medium, or expanded) for the window width
|
||||||
*
|
*
|
||||||
* @return width size class
|
* @return width size class
|
||||||
*/
|
*/
|
||||||
fun widthSizeClass(): WindowSizeClass {
|
fun widthSizeClass(): WindowWidthSizeClass {
|
||||||
return getWindowSizeClass(windowWidthDp)
|
return windowSizeClass.windowWidthSizeClass
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -157,8 +163,8 @@ data class WindowState(
|
||||||
*
|
*
|
||||||
* @return height size class
|
* @return height size class
|
||||||
*/
|
*/
|
||||||
fun heightSizeClass(): WindowSizeClass {
|
fun heightSizeClass(): WindowHeightSizeClass {
|
||||||
return getWindowSizeClass(windowHeightDp, Dimension.HEIGHT)
|
return windowSizeClass.windowHeightSizeClass
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -234,7 +240,8 @@ data class WindowState(
|
||||||
*/
|
*/
|
||||||
private fun windowIsLarge(): Boolean {
|
private fun windowIsLarge(): Boolean {
|
||||||
// Window is large if width size class is expanded and height size class is at least medium
|
// Window is large if width size class is expanded and height size class is at least medium
|
||||||
val isLarge = widthSizeClass() == WindowSizeClass.EXPANDED && heightSizeClass() != WindowSizeClass.COMPACT
|
val isLarge = widthSizeClass() == WindowWidthSizeClass.EXPANDED &&
|
||||||
|
heightSizeClass() != WindowHeightSizeClass.COMPACT
|
||||||
|
|
||||||
// Right now we are considering large screens + foldables mutually exclusive
|
// Right now we are considering large screens + foldables mutually exclusive
|
||||||
// (which seems necessary for dualscreen apps), but we may want to think about this
|
// (which seems necessary for dualscreen apps), but we may want to think about this
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the MIT License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.microsoft.device.dualscreen.windowstate
|
|
||||||
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import org.junit.Assert.assertEquals
|
|
||||||
import org.junit.Test
|
|
||||||
|
|
||||||
class WindowSizeClassTest {
|
|
||||||
@Test
|
|
||||||
fun width_returns_compact() {
|
|
||||||
assertEquals(WindowSizeClass.COMPACT, getWindowSizeClass(500.dp, Dimension.WIDTH))
|
|
||||||
assertEquals(WindowSizeClass.COMPACT, WindowState(windowWidthDp = 500.dp).widthSizeClass())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun width_returns_medium() {
|
|
||||||
assertEquals(WindowSizeClass.MEDIUM, getWindowSizeClass(700.dp, Dimension.WIDTH))
|
|
||||||
assertEquals(WindowSizeClass.MEDIUM, WindowState(windowWidthDp = 700.dp).widthSizeClass())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun width_returns_expanded() {
|
|
||||||
assertEquals(WindowSizeClass.EXPANDED, getWindowSizeClass(900.dp, Dimension.WIDTH))
|
|
||||||
assertEquals(WindowSizeClass.EXPANDED, WindowState(windowWidthDp = 900.dp).widthSizeClass())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun height_returns_compact() {
|
|
||||||
assertEquals(WindowSizeClass.COMPACT, getWindowSizeClass(300.dp, Dimension.HEIGHT))
|
|
||||||
assertEquals(WindowSizeClass.COMPACT, WindowState(windowHeightDp = 300.dp).heightSizeClass())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun height_returns_medium() {
|
|
||||||
assertEquals(WindowSizeClass.MEDIUM, getWindowSizeClass(700.dp, Dimension.HEIGHT))
|
|
||||||
assertEquals(WindowSizeClass.MEDIUM, WindowState(windowHeightDp = 700.dp).heightSizeClass())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun height_returns_expanded() {
|
|
||||||
assertEquals(WindowSizeClass.EXPANDED, getWindowSizeClass(1000.dp, Dimension.HEIGHT))
|
|
||||||
assertEquals(WindowSizeClass.EXPANDED, WindowState(windowHeightDp = 1000.dp).heightSizeClass())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -56,6 +56,7 @@ dependencies {
|
||||||
implementation androidxDependencies.ktxCore
|
implementation androidxDependencies.ktxCore
|
||||||
implementation androidxDependencies.appCompat
|
implementation androidxDependencies.appCompat
|
||||||
implementation androidxDependencies.window
|
implementation androidxDependencies.window
|
||||||
|
implementation androidxDependencies.windowCore
|
||||||
implementation composeDependencies.composeUI
|
implementation composeDependencies.composeUI
|
||||||
implementation composeDependencies.composeMaterial
|
implementation composeDependencies.composeMaterial
|
||||||
implementation composeDependencies.composeUITooling
|
implementation composeDependencies.composeUITooling
|
||||||
|
|
Загрузка…
Ссылка в новой задаче