Android 原生 Picture in Picture 画中画功能避坑指南 | 您所在的位置:网站首页 › 安卓设置弹窗怎么关闭啊苹果手机 › Android 原生 Picture in Picture 画中画功能避坑指南 |
最近生活有些变动所以断更好久,不过虽迟到但永远不会缺席。ChatGPT 浪潮还在持续扩大,各位同学一定要体验体验丫~ 这篇主要介绍最近需求中遇到的问题,希望能帮助后来者少踩坑。先说结论:Android 原生画中画功能并不完善,如果可以接受 APP 有两个任务栈则可以使用;否则趁早自己用浮窗自定义实现画中画的功能吧。 1. PiP 简介Android PiP 模式也称之为画中画模式,允许用户在使用应用程序的同时,在屏幕的一角或一侧浮动显示另一个应用程序或视频。这使得用户可以同时进行多项任务,而不必切换应用程序或中断正在进行的任务。如下所示:
官方文档:developer.android.google.cn/guide/topic… 官方Demo:github.com/android/med… 打开官方 Demo,首先得改一下 minSdkVersion,demo 里设置的是 API 31(Android 12.0),不满足实际应用需求,这里改为 23(Android 6.0). 但 PiP 功能只能在 Android8.0 及以上的系统上使用,所以用到一些方法时,需要注明 @RequiresApi(Build.VERSION_CODES.O)。所以,如果需要在 Android 8.0 以下的设备支持 PiP,只能使用自定义悬浮窗实现。 还需要注释掉 setAutoEnterEnabled(true)、setSeamlessResizeEnabled(false) 这两个方法。因为它们只能在 Android 12.0 及以上系统使用,且对于 PiP 的主体功能没有影响。setAutoEnterEnabled 用于设置 Activity 在退到后台时是否自动进入 PiP 模式,当设置为 true,则在用户点击 Home 键回到主屏幕时,Activity 可自动进入 PiP 模式,而不用开发者手动调用 enterPictureInPictureMode 方法;setSeamlessResizeEnabled 用于设置非视频画中画时的动画效果,不影响功能。 按照上述的内容设置完后就可以将 Demo 跑通了。 3. 示例代码分析仅分析查看了 Demo 中的 MovieActivity 中的 PiP 相关的代码。比较重要的代码如下: // code 1 @RequiresApi(Build.VERSION_CODES.O) private fun minimize() { enterPictureInPictureMode(updatePictureInPictureParams()) }调用 enterPictureInPictureMode(@NonNull PictureInPictureParams params) 方法就可以进入 PiP,声明如下: // code 2 public boolean enterPictureInPictureMode(@NonNull PictureInPictureParams params) { ··· }方法简介:它是 Activity 类中的方法,需要传递一个 PictureInPictureParams 类型对象。当系统成功将该 Activity 切换到 PiP 模式或已经处于 PiP,则返回值为 true;如果设备不支持 PiP 则返回 false。 再来看下构建 PictureInPictureParams 类型对象的 updatePictureInPictureParams() 方法: // code 3 @RequiresApi(Build.VERSION_CODES.O) private fun updatePictureInPictureParams(): PictureInPictureParams { // 1、计算出 PiP 小窗的宽高比,这里直接使用播放视频的控件宽和高计算 val aspectRatio = Rational(binding.movie.width, binding.movie.height) // 2、将播放视频的控件binding.movie设置为 PiP 中要展示的部分 val visibleRect = Rect() binding.movie.getGlobalVisibleRect(visibleRect) val params = PictureInPictureParams.Builder() .setAspectRatio(aspectRatio) // 3、指定进入画中画的屏幕部分。系统根据这个可实现平滑动画效果。这里就把之前生成的 visibleRect 传值过去 .setSourceRectHint(visibleRect) .build() setPictureInPictureParams(params) return params }updatePictureInPictureParams 方法作用是构建出进入 PiP 的一些参数,比如进入小窗的控件,小窗的宽高比等。注释很清楚,源码直接拿来套用就行。需要注意的点:只能指定 PiP 模式的宽高比,并不能直接设置宽和高的具体值,系统会根据设置的宽高比自己计算具体值。 如果在播放器控件上层有其他的操作按钮等,还需要在 onPictureInPictureModeChanged 回调中进行处理,即进入 PiP 后隐藏这些按钮;退出后恢复这些按钮的状态。 如下是 Demo 中的实现: // code 4 override fun onPictureInPictureModeChanged( isInPictureInPictureMode: Boolean, newConfig: Configuration ) { super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig) if (isInPictureInPictureMode) { // Hide the controls in picture-in-picture mode. binding.movie.hideControls() } else { // Show the video controls if the video is not playing if (!binding.movie.isPlaying) { binding.movie.showControls() } } }通过这个方法可以监听 PiP 的进入和退出。 还有一些是 PiP 模式下的播放/暂停、上一个/下一个 操作按钮,即下图红框中的这三个按钮,相关的使用方式 Demo 中已有示例,这里不再赘述。 除此之外,还要在需要进入 PiP 的 Activity 的 AndroidManifest 中设置支持 PiP 的属性以及处理布局配置更改。这样一来,如果在 PiP 模式转换期间出现布局更改,该 Activity 就不会重新启动。 // code 5 |
CopyRight 2018-2019 实验室设备网 版权所有 |