探索如何使用Android Jetpack组件折叠和展开设备。
近年来,科技界见证了可折叠设备的革命性趋势。这些设备融合了便携性和功能性的创新特点,使用户能够在不同的形态之间无缝切换。在本博客中,我们将深入探讨Android可折叠设备的世界,探索它们独特的特点、设计考虑因素,以及开发人员如何为这些设备创建优化的应用程序。
预计2023年可折叠手机出货量将达到2140万台,比2022年的1420万台增长50%。到2027年,这个数字将超过4810万台,年复合增长率为27.6%。尽管增长迅速,可折叠智能手机仍属于高端市场,平均售价预计在2023年下降6.8%。各公司正在投资软硬件改进,推动持续采用。
可折叠设备与传统智能手机和平板电脑完全不同。它们具有可以折叠和展开的柔性屏幕,可以实现多种使用场景。随着Android生态系统的扩展以支持这些设备,开发人员面临着激动人心的新挑战和机遇。
设计可折叠设备需要重新构思用户界面。随着设备的折叠和展开,应用程序需要优雅地适应不同的屏幕尺寸和方向。为了实现这一点,开发人员必须利用Android内置的可折叠和多窗口环境支持。
关键设计考虑因素:
https://source.android.com/docs/core/display/multi_display/multi-resume
Flex Mode: 可折叠设备通常支持“弯折模式”,屏幕部分折叠。应用程序应该针对此模式进行优化,使其布局适应可用的屏幕空间。
连续性:用户在从一个形态转换到另一个形态时应该体验到无缝的连续性。在这些转换过程中,数据和状态应该得到保留。要了解更多关于管理应用程序状态和连续性的信息,请参阅保存UI状态。
开发人员必须了解为可折叠设备引入的新功能和API,以创建充分利用其功能的应用程序。
https://source.android.com/docs/core/display/multi_display/multi-resume
https://developer.android.com/topic/arc/window-management
为可折叠设备调整现有应用程序涉及设计、布局和编码的调整。优先考虑核心功能,并在如何充分利用可折叠设备功能方面做出战略决策。
随着可折叠设备的普及,开发人员有机会塑造移动计算的未来。通过了解这些设备提供的独特挑战和可能性,开发人员可以创建出提供用户无与伦比的灵活性和功能性的应用程序。
以下是一个示例,演示如何在包含常用列表视图和详细视图屏幕的单个活动中处理可折叠和非可折叠设备:
Jetpack WindowManager库帮助应用程序开发人员支持新的设备形态,并在旧版和新版平台上提供各种WindowManager功能的公共API。将以下内容添加到您的app/build.gradle文件中。此设置增强了Android应用程序中的窗口管理和生命周期处理。
(Jetpack WindowManager)
https://developer.android.com/jetpack/androidx/releases/window
dependencies {
//need to get updates from window manager about layouts and screen
implementation('androidx.window:window-java:1.2.0')
implementation('androidx.window:window-rxjava2:1.2.0')
// need to use it for lifecycleScope to collect windowLayoutInfo
implementation('androidx.lifecycle:lifecycle-runtime-ktx:2.6.2')
}
您可以在lifecycleScope
中观察WindowInfoTracker
,并相应地更新您的用户界面。
//MainActivity.kt
lifecycleScope.launch(Dispatchers.Main) {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
WindowInfoTracker.getOrCreate(this@MainActivity)
.windowLayoutInfo(this@MainActivity)
.collect { updateUI(it) }
}
}
在这里,我们从WindowLayoutInfo
中获取displayFeatures
,并相应地展开或折叠。
//MainActivity.kt
private fun updateUI(windowLayoutInfo: WindowLayoutInfo) {
val displayFeature = windowLayoutInfo.displayFeatures
var isUnFold = false
for (feature in displayFeature) {
if (feature is FoldingFeature) {
val foldPos = feature.bounds.right
val foldWidth = feature.bounds.left - foldPos
expandLayout(foldPos, foldWidth)
isUnFold = true
}
}
if (!isUnFold) collapseLayout()
}
在这个方法中,我们通过折叠点的帮助启用了详细的屏幕布局。
//MainActivity.kt
private fun expandLayout(guidelinePosition: Int, foldWidth: Int) {
val listViewFragmentId = R.id.listViewFragmentContainer
val detailViewFragmentId = R.id.listViewDetailFragmentContainer
val landscapeLayout = ConstraintSet()
landscapeLayout.apply {
clone(binding.constraintLayout)
setMargin(detailViewFragmentId, ConstraintSet.START, foldWidth)
applyTo(binding.constraintLayout)
}
binding.guideline.setGuidelineEnd(guidelinePosition)
listViewFragment.setDetailViewContainerId(detailViewFragmentId)
fragmentManager.beginTransaction()
.replace(listViewFragmentId, listViewFragment)
.replace(detailViewFragmentId, detailViewFragment)
.commit()
}
这个方法将设置初始布局,并为列表屏幕布局设置用户界面。
//MainActivity.kt
private fun collapseLayout() {
val listViewFragmentId = R.id.listViewFragmentContainer
binding.guideline.setGuidelineEnd(0)
binding.listViewDetailFragmentContainer.visibility = View.GONE
listViewFragment.setDetailViewContainerId(listViewFragmentId)
fragmentManager.beginTransaction().replace(listViewFragmentId, listViewFragment).commit()
}
输出:
当我们没有添加WindowInfoTracker并且设备展开时的列表屏幕:
这是当我们添加了WindowInfoTracker
并且设备展开时的列表屏幕。它将同时显示详细屏幕:
Android对可折叠设备的支持得到了改善,专注于响应式设计。这使得应用程序能够适应不同的显示尺寸,给开发人员带来了挑战和机会。Android提供了创建响应式布局的资源。
https://developer.android.com/guide/topics/large-screens/multi-window-support
https://developer.android.com/guide/topics/resources/runtime-changes
https://developer.android.com/topic/libraries/architecture/saving-states