本文主要是对谷歌开发者官方微信公众号发布的Android 8.0 Oreo 画中画模式一文的学习记录。
画中画模式Picture-in-picture(PIP)简介
在Android 8.0(API Level 26)中,Activity可以启动画中画 Picture-in-picture(PIP)模式。PIP 是一种特殊类型的多窗口模式,常见于视频播放场景。Activity处于画中画模式时,是处于暂停状态的(onPause),但仍然可以继续展示内容,所以app不能在onPause()中停止播放,而应该在onStop()中停止,在onStart()中启动播放。
声明Activity支持画中画
从 Android 8.0(API 级别 26)开始,声明Activity支持PIP非常简单。只需在Manifest.xml中将Activity的supportsPictureInPicture标志置为true,不需要设置android:resizeableActivity为true,只有在声明Activity支持多窗口模式时,才需要设置android:resizeableActivity为true。
<activity
android:name=".MainActivity"
...
android:supportsPictureInPicture="true" />
如何进入画中画模式
public boolean enterPictureInPictureMode(PictureInPictureParams params)
PictureInPictureParams 的创建方式:
private void enterPIP() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Icon icon = Icon.createWithResource(MainActivity.this, R.drawable.ic_pause_24dp);
PendingIntent intent = PendingIntent.getBroadcast(MainActivity.this,
REQUEST_PAUSE,
new Intent(ACTION_MEDIA_CONTROL).putExtra(EXTRA_CONTROL_TYPE, CONTROL_TYPE_PAUSE),
0);
ArrayList<RemoteAction> actions = new ArrayList<>();
actions.add(new RemoteAction(icon, "PIP", "PIP", intent));
PictureInPictureParams.Builder builder = new PictureInPictureParams.Builder();
builder.setActions(actions);
enterPictureInPictureMode(builder.build());
}
}
注意
如果只是配置了android:supportsPictureInPicture="true"
,然后就在代码中进入画中画模式,我们可能会遇到:页面被销毁后重新启动并进入pause状态。现象就是:窗口是缩小了,但是视频却可能是重新开始播放的,这显然不是我们想要的。其生命周期变化如下:
这是因为,进入画中画模式,页面的纵横比可能发生了变化(尤其是应用全屏时是竖屏的状态),系统会以为页面从竖屏进入横屏模式,导致页面被销毁重新创建。
处理方法就是在Manifest的Activity节点下添加android:configChanges
配置,告诉系统哪些配置变化由app自己处理而不用重启页面,并按需要在onConfigurationChanged
回调中进行相应处理。
<activity
android:name=".MainActivity"
...
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:supportsPictureInPicture="true" />
画中画模式和全屏的转换
页面在进入画中画模式或恢复全屏时,我们可能有一些页面的显示细节要对应处理,这些处理可能放到Activity的onPictureInPictureModeChanged ( )的回调方法中。