从手机扩展到不同的大屏设备规格时,您需要考虑游戏如何处理窗口管理。在 Googlebook、ChromeOS 和 Google Play 游戏电脑版上,您的游戏可以在主桌面界面上的窗口模式下运行。在搭载 Android 12L(API 级别 32)或更高版本且屏幕宽度 > 600dp 的新 Android 平板电脑和可折叠设备上,您的游戏可以与其他应用并排在分屏模式下运行,可以调整大小,甚至可以在可折叠设备的内屏和外屏之间移动,从而导致窗口大小和(在某些设备上)屏幕方向发生配置更改。
基本的大屏配置
声明游戏是否能够处理调整大小:
<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 游戏电脑版配置图形功能。
大屏设备
为了在全屏模式下最大限度地扩大游戏在平板电脑、可折叠设备、Googlebook、ChromeOS 和连接的显示屏上的可视区域,请支持全屏沉浸模式,并通过在 decorView、系统界面可见性或 WindowInsetsCompat API 上设置标志来隐藏系统栏。您还需要妥善处理旋转和调整大小配置事件,或防止这些事件发生。
请注意,在 Android 大屏设备上,游戏可以在您可能尚未处理的配置中运行。如果游戏不支持所有窗口大小和屏幕方向配置,平台会在兼容模式下为游戏添加信箱模式,并在必要时提示玩家,然后再更改为不受支持的配置。
在某些设备上,当玩家切换到不受支持的配置时,系统可能会提示玩家选择重新加载游戏并重新创建 activity,以最适合新的窗口布局,但这会影响游戏体验。在各种多窗口模式配置(2/3、1/2、1/3 窗口大小)下测试游戏,并验证游戏内容或界面元素是否未被截断或无法访问。此外,还要测试游戏在可折叠设备上从内屏切换到外屏时,如何响应可折叠设备连续性。如果您发现问题,请明确处理这些配置事件,并添加高级大屏可调整大小支持。
高级大屏设备可调整大小性
如需退出兼容模式并避免重新创建 activity,请执行以下操作:
将主 activity 声明为可调整大小:
<android:resizeableActivity="true" />在游戏清单的
<activity>元素的android:configChanges属性中明确声明对“orientation”“screenSize”“smallestScreenSize”“screenLayout”和“density”的支持,以接收所有大屏配置事件:<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 是否在多窗口模式下运行。
在 Googlebook、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 布局库来支持可折叠设备折叠状态(例如桌面模式),以提高玩家的沉浸感和参与度:
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); }