Reputation: 480
I'm trying to apply the Jetpack WindowManager library’s WindowLayoutInfo class, which provides information about foldable displays (flat, half_opened, etc), im following the codelab for adaptative uis (url 01), in android studio, i created an instance of the emulator for a resizable device (this is experimental feature of last stable ide), but, when testing the app, the foldable states are the normal ones, checking the following function, it always returning the default posture (Normal):
I need some ideas for configuring the emulator for this feature. While unit testing is ok, the testing in the ui isnt checking the foldable state.
Thanks in advance.
Url 01: https://developer.android.com/codelabs/android-window-manager-dual-screen-foldables?hl=es-419#5
-- Kotlin code:
sealed interface DevicePosture {
object NormalPosture : DevicePosture
data class BookPosture(
val hingePosition: Rect
) : DevicePosture
data class Separating(
val hingePosition: Rect, var orientation: FoldingFeature.Orientation
) : DevicePosture
}
@OptIn(ExperimentalContracts::class)
fun isBookPosture(foldFeature: FoldingFeature?): Boolean {
contract { returns(true) implies (foldFeature != null) }
return foldFeature?.state == FoldingFeature.State.HALF_OPENED && foldFeature.orientation == FoldingFeature.Orientation.VERTICAL
}
@OptIn(ExperimentalContracts::class)
fun isSeparating(foldFeature: FoldingFeature?): Boolean {
contract { returns(true) implies (foldFeature != null) }
return foldFeature?.state == FoldingFeature.State.FLAT && foldFeature.isSeparating
}
/* ... */
val devicePostureFlow = WindowInfoTracker.getOrCreate(this).windowLayoutInfo(this)
.flowWithLifecycle(this.lifecycle)
.map { layoutInfo ->
val foldingFeature = layoutInfo.displayFeatures.filterIsInstance().firstOrNull()
when {
isBookPosture(foldingFeature) -> DevicePosture.BookPosture(foldingFeature.bounds)
isSeparating(foldingFeature) -> DevicePosture.Separating(foldingFeature.bounds, foldingFeature.orientation)
else -> DevicePosture.NormalPosture
}
}
.stateIn(
scope = lifecycleScope,
started = SharingStarted.Eagerly,
initialValue = DevicePosture.NormalPosture
)
-- I'm also following this tutorial from web: Large Screens & Foldables Tutorial for Android
Upvotes: 1
Views: 1950
Reputation: 38282
I would suggest taking the code snippet from the developer guide on Make your app fold aware. The essential section is "Features of foldable displays", that consists of two parts:
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED)
to ensure that the block is executed when the lifecycle is started and is cancelled when the lifecycle is stopped, and executed when the lifecycle is started again, etc.WindowInfoTracker.getOrCreate(this@MainActivity)
to collect displayFeatures
information. By placing it in that block, it's executed and cancelled at the right time together with the lifecycle.Upvotes: 0
Reputation: 71
For the resizable emulator, you can uncheck the Launch in the Running Devices tool window
option in Settings > Tools > Emulator.
Then, you will have access to Change posture
button in the sidebar.
However, it may be easier to just use a dedicated foldable emulator, like the 6.7 horizontal fold-in, 7.6 fold-in with outer display, 8 fold-out, or Pixel Fold. These will all have controls in the Extended Controls
three-dot menu under Virtual sensors
to change the device's posture.
Upvotes: 4