maqingqing edited this page Aug 18, 2017 · 3 revisions

适配 Android N 多窗口特性的 5 个要诀

英文原文:5 tips for preparing for Multi-Window in Android N

作者:Ian Lake, Google Android 技术推广工程师

翻译:Guokai Han

如果你看了What’s New in Android N这个视频,你会无意中发现了多窗口支持

使用多窗口分屏功能,能够并排地同时看到两个应用。你可能非常兴奋,想知道这是如何做到的,于是立刻去查阅文档,看看是什么新 API 实现了这一独特功能。

结果却发现并没有出现很多新的 API 。只有少量用于定制是否完全支持多窗口的 XML 属性以及少量用于检查当前是否处于多窗口模式的 Activity 方法。那这个魔法到底打是哪来的?其实魔法一直都在那

所谓的魔法就是 Android 的资源系统。资源系统中最强大的部分之一是提供替代资源(alternate resources )的能力——基于不同条件改变大小、布局、绘制、菜单等等。

**多窗口就是利用了这个资源系统 – 基于窗口大小来调整配置。**除了屏幕大小,最小宽度(即宽度或高度的最小值)和朝向(orientation)也会在调整窗口大小时更新。

这引出了我们第一个要诀。

要诀1:使用正确的上下文

使用适合的上下文(Context)加载合适的资源。如果你使用 Activity 上下文处理填充布局、获取资源等工作,这就对了。

然而,如果使用的是 Application 上下文处理 UI 相关的事情,你会发现加载的资源无法感知到多窗口。除了不会使用 Activity 主题的问题,你可能会加载了完全错误的资源!最好让你的 UI 资源与 Activity 上下文在一起。

要诀2:正确地处理配置变化

使用了正确的上下文,你要确保依据窗口大小获取正确的资源(无论之前是全屏还是两个应用的分屏)。重新加载这些资源的过程是基于你如何处理运行时变化的。

默认情况是你的整个 activity 被销毁然后再重建。这个过程会恢复你在 onSaveInstanceState() 方法中保存的所有状态,以及重新加载所有资源/布局。这个特性很好,你清楚所有事情都与新的配置一致并且配置的每种类型都被处理了。

不用说你也知道,每次配置变化的处理应该快速且流畅。请确保你没有在 onResume() 方法中做太多工作,并考虑使用 loaders 来保证配置变化时数据的连续。

你依然可以自己处理配置变化,在这种情况下你的 Activity (和 Fragment) 将收到 onConfigurationChanged() 方法回调而不是先销毁再重建,并且你需要手工管理视图更新,重新加载资源等工作。

要捕获多窗口相关的配置变化,你需要在 manifest 文件中添加一个 android:configChanges 属性,并至少设置这些值:

XHTML

<activity android:name=".MyActivity" android:configChanges="screenSize|smallestScreenSize |screenLayout|orientation" />

请确保你处理了所有可能需要变化的资源(当你自己负责处理配置变化时,这是你的责任了)。

这包括重新加载那些之前被认为是不变的资源。考虑一下你在 valuesvalues-sw600dp 中设置的大小。在非多窗口环境下,你无法在运行时切换它们,因为最小宽度是不变的(它总是设备的最小宽度)。然而在多窗口环境下,你可以且必需随着应用大小的调整而切换这些资源。

要诀3:处理所有朝向

回想下本文开头的介绍,我们谈到当窗口大小调整时朝向也会随之改变。没错,即使设备处于横屏的时候,应用也可能处于“竖屏”的朝向。

其实“竖屏”真正的意义仅仅是高度大于宽度,“横屏”的意义是宽度大于高度。所以从这个定义来考虑,在应用调整大小时,可能会从一个朝向转到另一个朝向就说得通了。

这也就是意味着朝向之间的转换应该尽可能平滑。引用 material design 规范中分屏部分的描述

改变设备的朝向不应该导致 UI 发生非预期的改变。例如,在某个分屏中(竖屏模式下)正在显示视频的应用,在旋转到横屏模式时,不应该自动进入全屏播放状态。

注意:如果你想要你的应用在全屏状态时(非多窗口)仍有这种类型的功能,你可以使用 inMultiWindowMode() 方法检查你当前所处的准确状态。

使用 android:screenOrientation 锁定屏幕朝向也会受到多窗口的影响。对于不是针对(target为) Android N 的应用,添加 android:screenOrientation 意味着你的应用根本不支持多窗口 – 这总是会强制用户离开多窗口模式。但在针对 Android N 的应用则稍有不同 – 在这种情况下不是不支持多窗口,而是处于多窗口模式时你在 android:screenOrientation 中设置的任何朝向都会被忽略。

请记住,无论应用是否针对 Android N,在多窗口模式下在运行时锁定朝向的 setRequestedOrientation() 方法都是无效的。

要诀4:针对所有屏幕尺寸构建响应式 UI

朝向并非是面向分屏设计的唯一问题。多窗口是平板 UI (tablet UI) 第一次遇到被缩小到微型尺寸的情况(你有平板 UI 吧?毕竟,14亿设备中的 12.5% 也是很多的设备)。

如果你已经在构建响应式 UI ,能够适应可用的空间,手机和平板有相对类似的布局,你会发现你已经为多窗口环境做了很好的准备。作为建议,把 UI 缩小到 220dp 的宽/高,然后让应用从这个大小扩展到全屏大小是你现在可做的事情

然而,如果你的手机和平板 UI 差异巨大,请不要迫使用户在这两者之间切换 – 而是以平板 UI 为主并想办法缩小它。有许多响应式 UI 模式可供你参考,它们可以为用户提供流畅的调整大小体验 – 再次说明,这些并不需要使用 Android N 的 API。

要诀5:由其它应用启动的 Activity 必需总是支持多窗口

在多窗口环境下,你的整个任务(task)都代表的是一个单窗口。这就是为什么如果要启动一个显示在(多窗口)旁边的 activity 需要启动一个新的任务 – 新任务才能是新窗口。

反过来也是如此,来自同一个页面中引用的内容:

如果你在一个任务堆栈中启动一个新的 activity,这个 activity 会替换屏幕上的当前 activity ,并且会继承所有它的多窗口属性

这意味着,如果你有一个能够被其它应用启动的 activity ,这个 activity 会继承调用方 activity 同样的多窗口属性。这些属性包括最小尺寸。如果使用的是 startActivityForResult() ,这种情况下你的 activity 必需是同一个任务堆栈的一部分,甚至在 implicit intent 的情况下也是如此。你无法确定别人是否使用了 FLAG_ACTIVITY_NEW_TASK

因此,所有这些直到最小尺寸的 activity (以及由 activity 启动的 activity)都必需支持多窗口。所以请彻底测试!

全面测试!

针对多窗口环境的最佳准备工作就是测试你的应用。即使没有修改任何代码,也没有配置过 Android N SDK ,只要把现有的应用安装到 Android N 设备或模拟器上就是很好的第一步,也是最容易做的事情。

Clone this wiki locally
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.