是时候学习Android分屏开发了

1,765 阅读7分钟

今年Google发布了Android N,Android N新增了不少功能,最受关注的自然就是分屏了。

这一功能对国内的很多手机用户并不陌生,其实很多第三方系统早已经实现了这一功能,如EMUI,Flyme等等。

分屏操作

在我的手机中,就可以一边看视频,一边浏览简书。Android N分屏功能的更新,似乎并不会对我国第三方Android系统带来多大的影响。毕竟厂商有自己实现这一功能的套路。

然而,谷歌反应的“缓慢”真的没有价值吗?其实不是的,Android N新增的功能是为其他第三方系统作出一个“标杆”。

这里举个例子,首先是分屏多任务,如今不同Android ROM实现该功能的方式不一,而且对软件的兼容也大有不同,所以体验也就可能差天共地(不能达到该有的标准),而Android N新增分屏多任务的支持,除了让第三方ROM开发商可以参照这个“模板”进行二次开发之外,软件开发人员也能根据Android N分屏多任务功能的实现方式去进行软件的开发。从而大大减少了自己摸索的时间,加快开发速度,由此支持该功能的软件会更多,兼容性也会更好。

分屏模式在Android电视中就变成了更为强大的画中画模式,终于可以一边看比赛直播,一边追电视剧了。

画中画

如何分屏呢

如果您的应用是使用 N Preview SDK 构建的,且未禁用多窗口支持,则应用默认支持分屏操作。

    compileSdkVersion 'android-N'
    buildToolsVersion "24.0.0 rc4"

    defaultConfig {
        applicationId "com.yll520wcf.myapplication"
        minSdkVersion 14
        targetSdkVersion 'N'
        versionCode 1
        versionName "1.0"
    }

用户可以通过以下方式切换到多窗口模式:

  1. 若用户打开最近任务列表(Overview 屏幕),并长按 Activity 标题,则可以拖动该 Activity 至屏幕突出显示的区域,使 Activity 进入多窗口模式。
  2. 若用户长按菜单按键(Overview 按钮),设备上的当前 Activity 将进入多窗口模式,同时将打开 最近任务列表(Overview 屏幕),用户可在该屏幕中选择要共享屏幕的另一个 Activity。

用户居然还可以在两个 Activity 共享屏幕的同时在这两个 Activity 之间拖放数据 (在此之前,用户只能在一个 Activity 内部拖放数据)。想想以后微博的图片直接拖到微信朋友圈中是不是很屌啊。

多窗口生命周期

还需要注意的是多窗口不会影响Activity的生命周期。

在多窗口模式中,在指定时间只有最近与用户交互过的 Activity 为活动状态。 该 Activity 将被视为顶级 Activity。 所有其他 Activity 虽然可见,但均处于暂停状态。 但是,这些已暂停但可见的 Activity 在系统中享有比不可见 Activity 更高的优先级。 如果用户与其中一个暂停的 Activity 交互,该 Activity 将恢复,而之前的顶级 Activity 将暂停。

在多窗口模式中,用户仍可以看到处于暂停状态的应用。 应用在暂停状态下可能仍需要继续其操作。 例如,处于暂停模式但可见的视频播放应用应继续显示视频。因此,我们建议播放视频的 Activity 不要在 onPause()方法中暂停视频,应在onStop()暂停视频播放,并在 onStart()中恢复视频播放。

用户使用多窗口模式显示应用时,系统将通知 Activity 发生配置变更。 该变更与系统通知应用设备从纵向模式切换到横向模式时的 Activity 生命周期影响基本相同,但设备不仅仅是交换尺寸,而是会变更尺寸。您的 Activity 可以自行处理配置变更,或允许系统销毁 Activity,并以新的尺寸重新创建该 Activity。

给Activity加上如下配置可以保证切换成多屏模式或者画中画模式时Activity不会销毁重建。

android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation">

针对多窗口进行配置

在清单文件的 或 节点中设置该属性,启用或禁用多窗口显示:

android:resizeableActivity=["true" | "false"]

如果该属性设置为 true,Activity 将能以分屏和自由形状模式启动。 如果此属性设置为 false,Activity 将不支持多窗口模式。 如果该值为 false,且用户尝试在多窗口模式下启动 Activity,该 Activity 将全屏显示。

如果您的应用面向 Android N,但未对该属性指定值,则该属性的值默认设为 true。 如果做电视开发或其它特殊需求,还有一个属性需要注意:

android:supportsPictureInPicture=["true" | "false"]

在清单文件的 节点中设置该属性,指明 Activity 是否支持画中画显示。如果 android:resizeableActivity为 false,将忽略该属性。

当然你还可以指定在自由形状模式时 Activity 的默认大小、位置和最小尺寸:

<activity android:name=".MainActivity">
    <layout android:defaultHeight="500dp"
          android:defaultWidth="600dp"
          android:gravity="top|end"
          android:minimalSize="450dp" />
</activity>

对于 Android N,清单文件元素支持以下几种属性,这些属性影响 Activity 在多窗口模式中的行为:

  1. android:defaultWidth 以自由形状模式启动时 Activity 的默认宽度。
  2. android:defaultHeight 以自由形状模式启动时 Activity 的默认高度。
  3. android:gravity 以自由形状模式启动时 Activity 的初始位置。
  4. android:minimalSize 分屏和自由形状模式中 Activity 的最小高度和最小宽度。 如果用户在分屏模式中移动分界线,使 Activity 尺寸低于指定的最小值,系统会将 Activity 裁剪为用户请求的尺寸。

多窗口模式中运行应用注意事项

在设备处于多窗口模式中时,某些功能会被禁用或忽略,因为这些功能对与其他 Activity 或应用共享设备屏幕的 Activity 而言没有意义。 此类功能包括:

  1. 某些自定义选项将被禁用;例如,在非全屏模式中,应用无法隐藏状态栏。
  2. 系统将忽略对 android:screenOrientation属性所作的更改

Activity类中添加了以下新方法,以支持多窗口显示。

  1. Activity.inMultiWindow() 调用该方法以确认 Activity 是否处于多窗口模式。
  2. Activity.inPictureInPicture() 调用该方法以确认 Activity 是否处于画中画模式。:画中画模式是多窗口模式的特例。 如果 myActivity.inPictureInPicture()返回 true,则 myActivity.inMultiWindow()也返回 true。
  3. Activity.onMultiWindowChanged() Activity 进入或退出多窗口模式时系统将调用此方法。 在 Activity 进入多窗口模式时,系统向该方法传递 true 值,在退出多窗口模式时,则传递 false 值。
  4. Activity.onPictureInPictureChanged() Activity 进入或退出画中画模式时系统将调用此方法。 在 Activity 进入画中画模式时,系统向该方法传递 true 值,在退出画中画模式时,则传递 false 值。

每个方法还有 Fragment版本,例如 Fragment.inMultiWindow()。

在多窗口模式中启动新 Activity

在启动新 Activity 时,用户可以提示系统如果可能,应将新 Activity 显示在当前 Activity 旁边。 要执行此操作,可使用标志Intent.FLAG_ACTIVITY_LAUNCH_TO_ADJACENT。传递此标志将请求以下行为:

  1. 如果设备处于分屏模式,系统会尝试在启动系统的 Activity 旁创建新 Activity,这样两个 Activity 将共享屏幕。 系统并不一定能实现此操作,但如果可以,系统将使两个 Activity 处于相邻的位置。
  2. 如果设备不处于分屏模式,则该标志无效。
    public void click(View v){
        Intent intent=new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);
        intent.setData(Uri.parse("http://www.baidu.com"));
        startActivity(intent);
    }

Paste_Image.png

支持拖放

用户可以在两个 Activity 共享屏幕的同时在这两个 Activity 之间拖放。因此,如果您的应用目前不支持拖放功能,您可以在其中添加此功能。

  1. android.view.DropPermissions令牌对象,负责指定对接收拖放数据的应用授予的权限。
  2. View.startDragAndDrop() View.startDrag()的新别名。要启用跨 Activity 拖放,请传递新标志 View.DRAG_FLAG_GLOBAL。如需对接收拖放数据的 Activity 授予 URI 权限,可根据情况传递新标志 View.DRAG_FLAG_GLOBAL_URI_READ或 View.DRAG_FLAG_GLOBAL_URI_WRITE。
  3. View.cancelDragAndDrop() 取消当前正在进行的拖动操作。只能由发起拖动操作的应用调用。
  4. View.updateDragShadow() 替换当前正在进行的拖动操作的拖动阴影。只能由发起拖动操作的应用调用。
  5. Activity.requestDropPermissions() 请求使用 DragEvent中包含的 ClipData传递的内容 URI 的权限。

参考文献

https://developer.android.com/preview/features/multi-window.html#running

最近开通了微信公众账号,大家捧场啊

微信公众账号:likeDev