从手机扩展到不同的大屏设备规格时,引入了有关游戏如何处理窗口管理的一些注意事项。在 ChromeOS 和 Google Play 游戏电脑版上,您的游戏可以通过主桌面界面在窗口模式下运行。在搭载 Android 12L(API 级别 32)或更高版本且屏幕宽度不低于 32 的新 Android 平板电脑和可折叠设备上600dp,那么在可折叠设备上,您的游戏可以在分屏模式下并排运行、调整大小,甚至在内外显示屏之间移动,这会导致窗口大小和在某些设备上屏幕方向的配置发生变化。
基本的大屏幕配置
声明您的游戏是否能够处理尺寸调整:
<android:resizeableActivity="true" or "false" />
如果无法支持尺寸调整,请确保游戏清单明确定义支持的最小和最大宽高比:
<!-- Render full screen between 3:2 and 21:9 aspect ratio -->
<!-- Let the platform letterbox otherwise -->
<activity android:minAspectRatio="1.5">
<activity android:maxAspectRatio="2.33">
Google Play 游戏电脑版
对于 Google Play 游戏电脑版,平台会处理窗口大小调整,同时遵循指定的宽高比。窗口大小会自动锁定为最佳尺寸。如果主要屏幕方向为横向,则宽高比必须至少为 16:9;如果游戏为纵向模式,则宽高比至少应为 9:16。为了获得最佳体验,请明确支持横屏游戏的宽高比为 21:9、16:10 和 3:2。窗口大小调整在此处不是必需的,但对于其他外形规格的兼容性而言,这仍然是不错的选择。
如需了解详情和最佳实践,请参阅针对 Google Play 游戏电脑版配置图形。
ChromeOS 和 Android 大屏设备
如需在 ChromeOS 和大屏 Android 设备上将游戏的全屏可见区域最大化,请支持全屏沉浸模式并隐藏系统栏,具体方法是:在 decorView
上设置标志、系统界面可见性,或通过 WindowInsetsCompat
API 进行设置。您还需要妥善处理旋转和大小调整配置事件,或防止这些事件发生在 ChromeOS 设备上。
请注意,在大屏 Android 设备上,您的游戏可以在您可能尚未处理的配置中运行。如果您的游戏仅支持部分窗口大小和方向配置,平台会在兼容模式下为游戏添加黑边,并在必要时先提示玩家,然后再更改为不受支持的配置。
![](https://developer.android.google.cn/static/images/games/multiplatform/configuration_compatibility_dialog.png?authuser=9&hl=sv)
在某些设备上,当玩家切换到不受支持的配置时,系统可能会提示他们重新加载游戏并重新创建 activity 以最好地适应新窗口布局,这会破坏游戏体验。在各种多窗口模式配置(2/3、1/2 和 1/3 窗口大小)下测试游戏,并验证是否有游戏内容、界面元素被截断或无法访问。此外,测试在可折叠设备上的内外屏幕之间移动时,游戏如何响应可折叠设备的连续性。如果您遇到问题,请明确处理这些配置事件,并添加高级大屏设备尺寸调整支持。
先进的大屏尺寸调整能力
如需退出兼容模式并避免重新创建 activity,请执行以下操作:
将主 activity 声明为可调整大小:
<android:resizeableActivity="true" />
声明对“orientation”“screenSize”“smallestScreenSize”“screenLayout”和“distribution”的明确支持在游戏清单
<activity>
元素的android:configChanges
属性中设置,以接收所有大屏设备配置事件:<android:configChanges="screenSize | smallestScreenSize | screenLayout | orientation | keyboard | keyboardHidden | density" />
替换
onConfigurationChanged()
并处理配置事件,包括当前屏幕方向、窗口大小、宽度和高度:Kotlin
override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) val density: Float = resources.displayMetrics.density val newScreenWidthPixels = (newConfig.screenWidthDp * density).toInt() val newScreenHeightPixels = (newConfig.screenHeightDp * density).toInt() // Configuration.ORIENTATION_PORTRAIT or ORIENTATION_LANDSCAPE val newScreenOrientation: Int = newConfig.orientation // ROTATION_0, ROTATION_90, ROTATION_180, or ROTATION_270 val newScreenRotation: Int = windowManager.defaultDisplay.rotation }
Java
@Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); float density = getResources().getDisplayMetrics().density; int newScreenWidthPixels = (int) (newConfig.screenWidthDp * density); int newScreenHeightPixels = (int) (newConfig.screenHeightDp * density); // Configuration.ORIENTATION_PORTRAIT or ORIENTATION_LANDSCAPE int newScreenOrientation = newConfig.orientation; // ROTATION_0, ROTATION_90, ROTATION_180, or ROTATION_270 int newScreenRotation = getWindowManager().getDefaultDisplay() .getRotation(); }
您还可以查询 WindowManager
来检查当前的设备旋转情况。根据这些元数据,检查新窗口尺寸并呈现为整个窗口的尺寸。由于宽高比差异,这可能并不适用于所有情况。因此,您也可以将游戏界面锚定到新的窗口大小,并使核心游戏内容进入信箱模式。如果这两种方法因技术或设计限制而无法使用,请自行在引擎内执行遮幅式黑边处理以保持宽高比,并在声明 resizeableActivity = false
并避免配置模式时缩放到最佳尺寸。
无论您采用何种方法,都应在不同的配置(折叠和展开、不同的旋转角度、分屏模式)下测试游戏,并确保游戏内界面元素不存在截断或重叠、触摸目标无障碍功能方面的问题,或宽高比问题导致游戏拉伸、挤压或扭曲。
此外,更大的屏幕通常意味着更大的像素,因为要在更大的屏幕中显示相同数量的像素。这可能会导致渲染缓冲区或分辨率较低的资源出现像素化问题。在大屏设备上使用最优质的素材资源并分析游戏的性能,确保不出现任何问题。如果您的游戏支持多个质量级别,请确保它能支持大屏设备。
多窗口模式
多窗口模式可让多个应用同时共享同一屏幕。多窗口模式不会更改 activity 生命周期;不过,在不同版本的 Android 上,应用在多个窗口中的恢复状态会有所不同(请参阅支持多窗口模式中的多窗口模式下的 activity 生命周期)。
当玩家将应用或游戏置于多窗口模式时,系统会通知 activity 发生配置变更,如高级大屏设备尺寸调整功能部分中所述。当玩家调整游戏大小或将游戏恢复到全屏模式时,也会发生配置更改。
无法保证应用在进入多窗口模式时能够重新获得焦点。因此,如果您使用任何应用状态事件来暂停游戏,请勿依赖获取焦点事件(焦点值为 true 的 onWindowFocusChanged()
)来恢复游戏。请改用其他事件处理脚本或状态更改处理脚本,例如 onConfigurationChanged()
或 onResume()
。请注意,您可以随时使用 isInMultiWindowMode()
方法检测当前 activity 是否是在多窗口模式下运行。
对于 ChromeOS 中的多窗口模式,初始窗口尺寸是一项重要的考虑因素。游戏不一定要全屏播放,您需要声明在这种情况下窗口的大小。建议您通过以下两种方式来处理此问题。
第一个选项通过在 Android 清单中的 <layout>
标记上使用特定属性来发挥作用。defaultHeight
和 defaultWidth
属性用于控制初始尺寸。您还应注意 minHeight
和 minWidth
属性,以防止玩家将游戏窗口大小调整为您不支持的尺寸。最后,gravity
属性用于确定窗口启动时窗口在屏幕上的显示位置。下面是一个使用这些属性的布局标记示例:
<layout android:defaultHeight="500dp"
android:defaultWidth="600dp"
android:gravity="top|end"
android:minHeight="450dp"
android:minWidth="300dp" />
用于设置窗口大小的第二个选项使用动态启动边界。您可以通过使用 setLaunchBounds(Rect)
定义起始窗口尺寸。如果指定了空矩形,则 activity 将以最大化状态启动。
此外,如果您使用的是 Unity 或 Unreal 游戏引擎,请确保您使用的是可为多窗口模式提供良好支持的最新版本(Unity 2019.4.40 和 Unreal 5.3 或更高版本)。
可折叠设备折叠状态支持
使用 Jetpack WindowManager 布局库支持可折叠设备折叠状态(例如桌面模式),以提高玩家的沉浸感和互动度:
![](https://developer.android.google.cn/static/images/games/multiplatform/foldable_posture_support.png?authuser=9&hl=sv)
Kotlin
fun isTableTopPosture(foldFeature : FoldingFeature?) : Boolean { contract { returns(true) implies (foldFeature != null) } return foldFeature?.state == FoldingFeature.State.HALF_OPENED && foldFeature.orientation == FoldingFeature.Orientation.HORIZONTAL }
Java
boolean isTableTopPosture(FoldingFeature foldFeature) { return (foldFeature != null) && (foldFeature.getState() == FoldingFeature.State.HALF_OPENED) && (foldFeature.getOrientation() == FoldingFeature.Orientation.HORIZONTAL); }