Chromebook 的屏幕尺寸兼容性

Chrome 操作系统上的 Android 应用实现提供了基本的多窗口支持。Chrome 操作系统上的 Android 应用会呈现在适合此类设备的布局中,而不是自动占据整个屏幕。

调整任务和窗口的大小

由于 Activity 的窗口大小可以改变,因此 Activity 应在启动时读取 Activity 分辨率。Activity 应通过调用 onConfigurationChanged(..) 来响应分辨率变化。例如,为了避免在最大化时丢失用户信息,您可以执行以下任一操作:

  • 通过向 Activity 的清单中添加 android:configChanges="screenSize|smallestScreenSize|orientation|screenLayout" 来动态处理配置更改。
  • 通过使用 onSaveInstanceState 恢复先前的状态,尽可能地简化转换过程。这在除了请求重启别无选择的情况下适用。

查找当前配置时,应始终在 getResources().getConfiguration() 中使用当前 Activity 的配置。请勿使用后台 Activity 或系统资源的配置。后台 Activity 没有大小,而系统的配置可能会包含大小和方向冲突的多个窗口,因此无法提取可用的数据。

另一个重要的考虑因素是窗口内容边界可能会发生变化。例如,如果窗口太大以致屏幕容纳不下,那么应用使用的窗口区域就可能会发生变化。请考虑以下准则:

  • 利用 Android 布局过程的应用应自动在可用空间中进行布局。
  • 原生应用应读取可用区域并监控大小变化,以避免出现无法访问的界面元素。您可以调用以下方法来确定相应界面的初始可用大小:
    • NativeActivity.mLastContent[X/Y/Width/Height]()
    • findViewById(android.R.id.content).get[Width/Height]()
    您可以通过观察器进行持续监控:
    • NativeActivity.onContentRectChangedNative()
    • NativeActivity.onGlobalLayout()
    • view.addOnLayoutChangeListener(findViewById(android.R.id.content)) 中添加监听器
    如果应用预缩放其图片,则每次分辨率发生变化时都应执行此操作。

系统支持自由大小调整;不过,并非所有应用在编写时都考虑到了大小调整。下面是您需要注意的一些潜在问题:

  • 无缝处理大小调整。您可以在任何时候、出于任何原因调整大小。因此,在需要重启时,必须能够通过 onSaveInstanceState 尽可能好地保存和恢复状态。请注意,总的来说,这对 Android 也有好处。
  • 此外,还应通过缓存先前分配的对象来确保实现快速的 Activity 重启。如果您不使用框架布局机制(其结果包括应用会使用 OpenGL 并扩展内容等),或者其他某种逻辑开始发挥作用,则应监听 onConfigurationChanged 事件以避免 Activity 重启。请务必指定您可以动态处理的所有更改事件。
  • 如果您不想调整大小,则应在清单文件中相应地指定这一点。
  • 务必注意,窗口大小不是屏幕尺寸,您可能永远都不需要知道屏幕尺寸。如需获取窗口大小,您应使用 Activity.getResources().getConfiguration().screenWidthActivity.getResources().getConfiguration().screenHeight(以 DP 为单位)。

如需获取当前配置,请始终使用 Activity 的资源并从中获取配置,否则您可能只能通过查看屏幕属性等内容来获取相关信息。

请注意,屏幕位置也可能会发生变化。因此,请务必始终使用系统进行窗口到屏幕的空间计算,反之亦然。

如果您使用 Android 的视图系统,则窗口应该会随着大小的变化自动进行布局。

如果您不使用视图系统并接管界面,则您的应用必须自行处理大小变化。

原生应用应使用 mLastContent 成员或通过获取内容视图来获取初始大小。

应用运行后,应监听 onContentRectChangedNativeonGlobalLayout 事件来响应大小变化。

请注意,大小发生变化后,应用应重新缩放或重新加载布局和图片并更新输入区域。

布局

如需在屏幕上填入更多信息,您可以指定不同的布局,也可以根据请求的大小动态创建布局。请注意,通常不建议动态生成布局,但有时可能会发生。

不使用布局系统的应用应避免在配置更改后重启,因为这样做可能成本非常高昂。导致发生这些更改的原因,有些显而易见,比如窗口大小变化,有些则并不明显,比如设备模式转换。例如,从笔记本电脑变为平板电脑后,系统会报告发生了配置更改,因为物理键盘消失了。如果重启会让用户等待甚至意外丢失工作数据,则会给他们带来不良体验。

请确保您的代码不会因动态调整大小操作而尝试访问已消失的界面元素。

监控视图层次结构更改

添加窗口控件标题可能会导致一些问题。请考虑以下建议:

  • 不要认为内容会从窗口的 (0,0) 处开始。窗口内容可能会按标题的高度偏移。您可以使用 View.getLocationInWindow() 查看视图的屏幕位置,以获取正确的偏移量。
  • 不要认为 DecorViewcontentView 的持有者。标题是窗口层次结构的一部分,如果存在,它会位于 DecorView 与内容视图之间。因此,请遵循以下准则:
    • 不要直接在 DecorView 下面更改视图层次结构。
    • 不要假定 DecorView 的子级的类型为 LinearLayout
  • 不要假设 Configuration.screenHeightDp 是应用内容区域的高度。此高度的一部分由标题视图(如果存在)占用。这同样适用于 Display.getSize(),等等。

其他注意事项

下面是您需要考虑的其他一些方面:

  • 如果 Activity 应始终在全屏模式下运行,请向清单中添加 android:resizeableActivity="false" 标记。
  • 向最终用户显示窗口控件,用于在所有可用布局之间切换。通过选择正确的屏幕方向选项,您可以确保用户在启动应用时获得正确的布局。如果应用支持纵向和横向模式,则默认为横向模式(如有可能)。设置此选项后,系统会按应用记住相应设置。
  • 设法避免不必要的屏幕方向更改。例如,如果 Activity 屏幕方向为“纵向”,但应用在运行时调用 setRequestedOrientation(LANDSCAPE),就会导致不必要的窗口大小调整,这样会让用户感到厌烦,而且如果应用无法处理,还可能会重启。首选方法是设置一次屏幕方向(例如,在清单中设置),并只有在必要时才进行更改。
  • 不要在 Activity 的 onDestroy 方法中调用 finish()。这样做会导致应用在调整大小时关闭而不是重启(假定应用必须重启)。
  • 不要使用不兼容的窗口类型,如 TYPE_KEYGUARDTYPE_APPLICATION_MEDIA

注意:我们建议您对应用进行测试,以确保其能够妥善处理窗口大小的变化。