英文:
How to handle device fold postures using the emulator in android studio
问题
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):
我正在尝试应用Jetpack WindowManager库的WindowLayoutInfo类,该类提供了关于可折叠显示屏的信息(平面、半开启等),我正在按照自适应用户界面的代码实验(链接01)在Android Studio中进行,我创建了一个可调整大小的设备模拟器实例(这是最新稳定IDE的实验性功能),但是在测试应用时,可折叠状态始终是正常的状态,检查以下函数,它始终返回默认的姿势(正常):
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.
我需要一些关于配置模拟器以支持此功能的想法。虽然单元测试正常,但UI测试未检查可折叠状态。
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<FoldingFeature>().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
我还在网上关注这个教程:Android大屏幕和可折叠设备教程
英文:
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
答案1
得分: 1
对于可调整大小的模拟器,您可以在设置 > 工具 > 模拟器中取消选中在运行设备工具窗口中启动
选项。
然后,您将在侧边栏中获得更改姿势
按钮。
然而,使用专用的可折叠模拟器可能更容易,例如6.7英寸横向折叠、7.6英寸外屏幕折叠、8英寸展开或Pixel Fold。这些都将在扩展控制
下的虚拟传感器
菜单中具有控制选项,以更改设备的姿势。
英文:
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.
答案2
得分: 0
我建议从使您的应用程序支持折叠屏开发者指南中提取代码片段。其中关键部分是“折叠屏显示的特性”包含两个部分:
-
在
lifecycleScope
内部,我们使用lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED)
来确保当生命周期启动时执行该代码块,并在生命周期停止时取消执行,然后在生命周期再次启动时重新执行,依此类推。 -
该代码块然后执行
WindowInfoTracker.getOrCreate(this@MainActivity)
来收集displayFeatures
信息。通过将它放在该代码块中,它将在正确的时间与生命周期一起执行和取消。
英文:
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:
- Inside the lifecycleScope, we use
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. - That block then executes
WindowInfoTracker.getOrCreate(this@MainActivity)
to collectdisplayFeatures
information. By placing it in that block, it's executed and cancelled at the right time together with the lifecycle.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论