Android N 预览版本支持画中画(Picture in Picture)模式进行视频的播放。画中画是多窗口模式的一种特殊类型,主要用于后台播放视频。Android TV设备早已经支持画中画模式。在多窗口模式中,用户仍然可以看到处于暂停状态的应用,而且应用在暂停状态下可能仍需要继续其他操作。例如,处于暂停模式但可见的视频播放应用应该继续显示视频。Android官方建议播放视频的Activity不要在onPause()暂停视频,应在onStop()暂停视频,在onStart()恢复播放。先看下画中画播放视频的情景:

在Android N 版本中,你可以在manifest文件对Activity是否支持多窗口形式进行设置。根Activity的属性设置适用于其任务栈所有Activity。支持多窗口设置如下:

android:resizeableActivity="true"

如果设为true,Activity将可以分屏和以自由模式启动;如果为false,则不支持分屏。该属性默认为true。如果需要 支持画中画模式,设置如下:

android:supportsPictureInPicture="true"

和多窗口布局属性相关的包括:默认高度、默认宽度、初始位置、最小高度、最小宽度。具体如下:

<layout
android:defaultHeight="500dp"//设置默认高度
android:defaultWidth="600dp"//设置默认宽度
android:gravity="top|end"//设置初始位置
android:minimalHeight="450dp"//设置最小高度
android:minimalWidth="300dp"//设置最小宽度
/>

如果需要查询当前Activity是否处于多窗口模式,可以调用以下方法:

Activity.isInMultiWindowMode()

如果需要查询当前Activity是否处于画中画模式,可以调用以下方法:

Activity.isInPictureInPictureMode()

Activity 进入或退出多窗口模式时系统将调用如下方法。 在 Activity 进入多窗口模式时,系统向该方法传递 true 值,在退出多窗口模式时,则传递 false 值。

Activity.onMultiWindowModeChanged()

Activity 进入或退出画中画模式时系统将调用如下方法。 在 Activity 进入画中画模式时,系统向该方法传递 true 值,在退出画中画模式时,则传递 false 值。

Activity.onPictureInPictureModeChanged()

如果需要在画中画模式中启动Activity,可以调用如下方法:

Activity.enterPictureInPictureMode()

在多窗口模式中启动新 Activity,可以使用标志 Intent.FLAG_ACTIVITY_LAUNCH_TO_ADJACENT。如果设备处于分屏模式,系统会尝试在启动系统的 Activity 旁创建新 Activity,这样两个 Activity 将共享屏幕。如果设备处于自由形状模式,则在启动新 Activity 时,用户可通过调用 ActivityOptions.setLaunchBounds() 指定新 Activity 的尺寸和屏幕位置。值得注意的是,如果您在任务栈中启动 Activity,该 Activity 将替换屏幕上的 Activity,并继承其所有的多窗口属性。 如果要在多窗口模式中以单独的窗口启动新 Activity,则必须在新的任务栈中启动此 Activity。Activity处于画中画模式时,生命周期应该这样操作:

@Override
protected void onStop() {super.onStop();//进入画中画模式,调用onPause方法,而不是onStop方法//暂停视频的播放mMovieView.pause();
}@Override
protected void onRestart() {super.onRestart();//恢复视频的播放mMovieView.showControls();
}@Override
public void onConfigurationChanged(Configuration newConfig) {super.onConfigurationChanged(newConfig);//屏幕发生旋转,自适应全屏adjustFullScreen(newConfig);
}@Override
public void onWindowFocusChanged(boolean hasFocus) {super.onWindowFocusChanged(hasFocus);if (hasFocus) {//window获得焦点,自适应全屏adjustFullScreen(getResources().getConfiguration());}
}Activity进入或者画中画时,需要重写onPitctureInPictureModeChanged方法:
@Overridepublic void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {super.onPictureInPictureModeChanged(isInPictureInPictureMode);if (isInPictureInPictureMode) {// 开始接受来自画中画点击响应事件mReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {if (intent == null || !ACTION_MEDIA_CONTROL.equals(intent.getAction())) {return;}// 点击后的回调final int controlType = intent.getIntExtra(EXTRA_CONTROL_TYPE, 0);switch (controlType) {case CONTROL_TYPE_PLAY:mMovieView.play();break;case CONTROL_TYPE_PAUSE:mMovieView.pause();break;}}};registerReceiver(mReceiver, new IntentFilter(ACTION_MEDIA_CONTROL));} else {// 退出画中画 模式,注销广播,不再接收点击响应事件unregisterReceiver(mReceiver);mReceiver = null;if (mMovieView != null && !mMovieView.isPlaying()) {mMovieView.showControls();}}}

视频状态发生改变时,调用以下方法按钮和文字的状态:

/*** 处于画中画模式,更新播放/暂停状态** @param iconId      图标的id* @param title       标题* @param controlType 控制类型:播放/暂停* @param requestCode 使用PendingIntent的请求码*/
void updatePictureInPictureActions(@DrawableRes int iconId, String title, int controlType,int requestCode) {final ArrayList<RemoteAction> actions = new ArrayList<>();//当用户点击控制按钮时,PendingIntent会被调用final PendingIntent intent = PendingIntent.getBroadcast(MainActivity.this,requestCode, new Intent(ACTION_MEDIA_CONTROL).putExtra(EXTRA_CONTROL_TYPE, controlType), 0);final Icon icon = Icon.createWithResource(MainActivity.this, iconId);actions.add(new RemoteAction(icon, title, title, intent));actions.add(new RemoteAction(Icon.createWithResource(MainActivity.this, R.drawable.ic_info_24dp),getString(R.string.info), getString(R.string.info_description),PendingIntent.getActivity(MainActivity.this, REQUEST_INFO,new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.info_uri))),0)));mPictureInPictureArgs.setActions(actions);//设置画中画参数setPictureInPictureArgs(mPictureInPictureArgs);
}

视频播放回调,包括播放、暂停和最小会窗口,每个接口会调用上面介绍到的方法更新状态:

/*** 视频播放的回调*/
private MovieView.MovieListener mMovieListener = new MovieView.MovieListener() {@Overridepublic void onMovieStarted() {// 处于画中画模式,播放视频时,显示暂停按钮updatePictureInPictureActions(R.drawable.ic_pause_24dp, mPause, CONTROL_TYPE_PAUSE,REQUEST_PAUSE);}@Overridepublic void onMovieStopped() {// 处于画中画模式,暂停视频时,显示播放按钮updatePictureInPictureActions(R.drawable.ic_play_arrow_24dp, mPlay, CONTROL_TYPE_PLAY,REQUEST_PLAY);}@Overridepublic void onMovieMinimized() {// 进入画中画模式,播放窗口最小化minimize();}};

好了,以上是对Android N多窗口和画中画模式的介绍。如果这篇文章对你有帮助,可以点个赞。

Android N 多窗口的应用——画中画相关推荐

  1. Android N 多窗口模式

    前言  在智能手机更新换代越来越快,手机屏幕越来越大,手机可以做的事情越来越多,人们已经离不开智能手机了,甚至有的人开始在用手机办公了.在大屏幕手机上,如果一个手机可以一边播放视频,一边上着网,那种体 ...

  2. Android应用程序窗口(Activity)的测量(Measure)、布局(Layout)和绘制(Draw)过程分析(上)...

    在前面一篇文章中,我们分析了Android应用程序窗口的绘图表面的创建过程.Android应用程序窗口的绘图表面在创建完成之后,我们就可以从上到下地绘制它里面的各个视图了,即各个UI元素了.不过在绘制 ...

  3. Android应用程序窗口(Activity)的视图对象(View)的创建过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8245546 从前文可知道,每一个Activit ...

  4. android弹出窗口的实现(PopupWindow)

    android弹出窗口的实现(PopupWindow)         最近看到新浪微博顶部栏的微博分组效果很炫,从网上查了一些资料明白原来是用PopupWindow实现的,今天自己也写了一个例子实现 ...

  5. Android应用程序窗口(Activity)的窗口对象(Window)的创建过程分析

    在前文中,我们分析了Android应用程序窗口的运行上下文环境的创建过程.由此可知,每一个Activity组件都有一个关联的ContextImpl对象,同时,它还关联有一个Window对象,用来描述一 ...

  6. android中弹出窗口,如何在Android中创建弹出窗口(PopupWindow)

    如何制作一个简单的Android弹出窗口 这是一个更完整的例子.这是一个补充性答案,涉及一般情况下创建弹出窗口的过程,而不一定是OP问题的具体细节.(OP要求取消按钮,但这不是必需的,因为用户可以在屏 ...

  7. Android应用程序窗口(Activity)与WindowManagerService服务的连接过程分析

    在前两文中,我们分析了Activity组件的窗口对象和视图对象的创建过程.Activity组件在其窗口对象和视图对象创建完成之后,就会请求与WindowManagerService建立一个连接,即请求 ...

  8. Android应用程序窗口(Activity)的运行上下文环境(Context)的创建过程分析

    出自:http://blog.csdn.net/luoshengyang/article/details/8201936 在前文中,我们简要介绍了Android应用程序窗口的框架.Android应用程 ...

  9. Android Studio 工具窗口浮动与布局恢复【申明:来源于网络】

    Android Studio 工具窗口浮动与布局恢复[申明:来源于网络] http://bbs.chinaunix.net/thread-4182438-1-1.html 转载于:https://ww ...

最新文章

  1. 第2节 mapreduce深入学习:4, 5
  2. $\mathbf{R}^n$中的紧集是闭有界集
  3. 结课作业:云计算在物联网中的应用发展
  4. No module named 'numpy.core._multiarray_umath'
  5. IOS学习笔记之十一(包装类、description、isequal)
  6. 速途网范锋:我的创业路早已命中注定
  7. C#转C++的一点分享
  8. fragment的懒加载
  9. UVA10189 Minesweeper【Ad Hoc】
  10. 从Hadoop看普通算法在一个系统中的应用
  11. 第六章 jQuery中的Ajax应用
  12. 论文笔记_S2D.45_ORBSLAM-Atlas: 一个稳健和精确的多建图系统
  13. 监控延迟严重怎么解决_监控画面故障解决:网络监控画面没有图像显示或无视频信号怎么办...
  14. 使用Fiddler进行http抓包和调试
  15. 汽车行业如何进行数字化转型
  16. ubuntu22.04在虚拟机中的安装过程以及搜狗输入法的安装
  17. vue.js安装步骤教程
  18. 投稿Springer旗下某中科院1区TOP期刊时间记载
  19. PHP容器--Pimple运行流程浅析
  20. Python|Leetcode《306》|累加数

热门文章

  1. BUUCTF ZIP伪加密
  2. win10 edge浏览器打不开
  3. win10中Edge浏览器打不开网页 崩溃 兼容性问题 STATUS_INVALID_IMAGE_HASH
  4. 无刷直流电机驱动器性能指标
  5. 电池管理系统之神奇的BMS(一)
  6. 科研画图工具origin9.1绿色版本_解决图形水印问题
  7. 逆变器方案(工频全套)工频正弦波逆变器开发板全套设计资
  8. 2-31 HTML2CSS
  9. 使用mysql 作数据仓库_从MYSQL迁移数据到华为云数据仓库服务经验总结
  10. 3dmax基本建模 - 做一个简单四合院