Android 8.0 Api 26以上 已允许画中画模式启动,主要用于播放视频。
第一步
默认情况下,系统不自动支持应用程序的PIP。
通过将设置android:supportsPictureInPicture为来在清单中注册视频活动 true
<activity android:name=".MainActivity"
android:supportsPictureInPicture="true"
android:configChanges=
"screenSize|smallestScreenSize|screenLayout|orientation">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
第二步
调用 enterPictureInPictureMode() 就可以开启画中画模式了。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
enterPictureInPictureMode();
}
到这里已经实现了画中画的雏形了。可以看到画中画中显示的少部分界面,官方建议画中画中只播放视频,所以就需要自己操作页面,除了视频播放控件,把其他全部隐藏。就会用到下面这个回调。
onPictureInPictureModeChanged(boolean isInPictureInPictureMode, Configuration newConfig)
当进入或退出画中画模式后都会回调,isInPictureInPictureMode为true时,是进入画中画(也就是变成小窗后),退出画中画时未false。
@Override
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode, Configuration newConfig) {
super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig);
if (isInPictureInPictureMode) {
mTvTitle.setVisibility(View.GONE);
mIv.setVisibility(View.GONE);
mPinp.setVisibility(View.GONE);
} else {
mTvTitle.setVisibility(View.VISIBLE);
mIv.setVisibility(View.VISIBLE);
mPinp.setVisibility(View.VISIBLE);
}
}
添加播放视频控件 SurfaceView + MediaPlayer
mSurfaceViewHolder = mSurfaceView.getHolder();
mediaPlayer = MediaPlayer.create(this, R.raw.vid_bigbuckbunny);
mSurfaceViewHolder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
mediaPlayer.setDisplay(mSurfaceViewHolder);
mediaPlayer.start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
});
这样就可以把画中画的视频播放起来了,但是发现进入画中画之后视频就暂停播放了,退出画中画模式后又会继续播放,我们希望,无论进入还是退出画中画的视频都能继续进行。
解决办法:
在官方文档介绍了,在进入和退出画中画时都会回调当前activity的 onStop()和onStart()。在onStop()和onStart()中继续播放视频。
@Override
protected void onResume() {
Log.d("MainActivity", "onResume");
if (mediaPlayer != null){
mediaPlayer.start();
}
super.onResume();
}
@Override
protected void onStop() {
Log.d("MainActivity", "onStop");
mediaPlayer.pause();
super.onStop();
}
但是我认为在生命周期中操作视频的播放,就把逻辑扩大化了,示例中只是为了学习画中画案例才写到生命周期中,当业务复杂时,或者逻辑校验不成熟时,都会导致bug的发生。onPictureInPictureModeChanged()回调函数中操作思路清晰,操作和业务逻辑都在一条业务线上。
到这就不往下继续实现了,因为可做的东西实在太多了,在其他示例中都包含这些部分。包括画中画的显示大小,画中画显示中的暂停、快进、快退、音量的按钮,全屏显示时视频播放的大小,显示视频详情时,向上滑动自动进入画中画模式等等。