Android当中,悬浮窗口和画中画相机的区别是什么

主题信息(必填)
主题描述(最多限制在50个字符)
申请人信息(必填)
申请信息已提交审核,请注意查收邮件,我们会尽快给您反馈。
如有疑问,请联系
CSDN &《程序员》研发主编,投稿&纠错等事宜请致邮
你只管努力,剩下的交给时光!
如今的编程是一场程序员和上帝的竞赛,程序员要开发出更大更好、傻瓜都会用到软件。而上帝在努力创造出更大更傻的傻瓜。目前为止,上帝是赢的。个人网站:www.xttblog.com。个人QQ群:、
个人大数据技术博客:https://www.iteblog.com2519人阅读
android开发(37)
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"
和多窗口布局属性相关的包括:默认高度、默认宽度、初始位置、最小高度、最小宽度。具体如下:
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();
protected void onRestart() {
super.onRestart();
//恢复视频的播放
mMovieView.showControls();
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
//屏幕发生旋转,自适应全屏
adjustFullScreen(newConfig);
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {//window获得焦点,自适应全屏
adjustFullScreen(getResources().getConfiguration());
Activity进入或者画中画时,需要重写onPitctureInPictureModeChanged方法:
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
super.onPictureInPictureModeChanged(isInPictureInPictureMode);
if (isInPictureInPictureMode) {
// 开始接受来自画中画点击响应事件
mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
if (intent == null || !ACTION_MEDIA_CONTROL.equals(intent.getAction())) {
// 点击后的回调
final int controlType = intent.getIntExtra(EXTRA_CONTROL_TYPE, 0);
switch (controlType) {
case CONTROL_TYPE_PLAY:
mMovieView.play();
case CONTROL_TYPE_PAUSE:
mMovieView.pause();
registerReceiver(mReceiver, new IntentFilter(ACTION_MEDIA_CONTROL));
// 退出画中画 模式,注销广播,不再接收点击响应事件
unregisterReceiver(mReceiver);
mReceiver =
if (mMovieView != null && !mMovieView.isPlaying()) {
mMovieView.showControls();
视频状态发生改变时,调用以下方法按钮和文字的状态:/**
* 处于画中画模式,更新播放/暂停状态
* @param iconId
* @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))),
mPictureInPictureArgs.setActions(actions);
//设置画中画参数
setPictureInPictureArgs(mPictureInPictureArgs);
视频播放回调,包括播放、暂停和最小会窗口,每个接口会调用上面介绍到的方法更新状态:/**
* 视频播放的回调
private MovieView.MovieListener mMovieListener = new MovieView.MovieListener() {
public void onMovieStarted() {
// 处于画中画模式,播放视频时,显示暂停按钮
updatePictureInPictureActions(R.drawable.ic_pause_24dp, mPause, CONTROL_TYPE_PAUSE,
REQUEST_PAUSE);
public void onMovieStopped() {
// 处于画中画模式,暂停视频时,显示播放按钮
updatePictureInPictureActions(R.drawable.ic_play_arrow_24dp, mPlay, CONTROL_TYPE_PLAY,
REQUEST_PLAY);
public void onMovieMinimized() {
// 进入画中画模式,播放窗口最小化
minimize();
好了,以上是对Android N多窗口和画中画模式的介绍。如果这篇文章对你有帮助,可以点个赞。他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)今天继续上一篇Android顶层窗口、浮动窗口的进阶应用。上一篇主要讲解了WindowManager服务和如何使用WindowManager编写一个顶层窗口。今天主要是讲讲如何在顶层窗口里面播放视频,这个功能对很多嵌入式设备来说十分有用。例如现在手机和平板上一些视频播放器就可以实现画中画功能,只显示一部分小窗口播放,用户可以继续操作其他功能。当你在看视频的时候收到短信,你只要进入画中画功能,视频可以继续播放,同时你可以去操作短信功能。
(PS:新建的Q_Q_群,有兴趣可以加入一起讨论:Android群:)
1、MediaPlayer视频播放
视频播放使用Android自带的播放功能,下面简单介绍一下MediaPlayer的使用。MediaPlayer使用其实十分方便,不过它支持的格式并不多,不过这里主要是为了演示如何实现画中画功能。因为后面打算把这个画中画功能加入到VLC播放器里面,这样就可以解决支持格式不多问题。
//Edited by mythou
// 播放界面使用surfaceview实现
surfaceView = (SurfaceView) mlayoutView.findViewById(R.id.myView);
//获取surfaceHolder,控制surfaceview
surfaceHolder = surfaceView.getHolder();
//回调,检测surfaceview的三种状态
surfaceHolder.addCallback(this);
//surfaceview的显示源类型
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
//mediaplayer初始化
mediaPlayer = new MediaPlayer();
//设置不同的监听接口
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnErrorListener(this);
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnSeekCompleteListener(this);
mediaPlayer.setOnVideoSizeChangedListener(this);
String filePath = "/mnt/card/test.mp4";// "/mnt/sdcard/test.mp4";//
// 本地地址和网络地址都可以
mediaPlayer.setDataSource(filePath);
catch (IllegalArgumentException e)
// TODO: handle exception
Log.v(LOGCAT, e.getMessage());
上面是初始化surfaceView和MeidaPlayer的代码,surfaceview在android应用开发里面十分重要,基本上设计视频或者动画类型的界面,都需要用到它。如果不了解的朋友,建议好好去熟悉一下这个类的使用。下面我们看看surfaceview的回调接口:
//Edited by mythou
  @Override
public void surfaceCreated(SurfaceHolder holder)
Log.v(LOGCAT, "suc calles");
mediaPlayer.setDisplay(holder);// 若无次句,将只有声音而无图像
       //播放视频
mediaPlayer.prepare();
} catch (IllegalStateException e)
} catch (IOException e)
上面是surfaceview里面其中一个回调接口,在这里我们处理视频准备开始播放,以及把surfaceview设置到MediaPlayer里面,让他们两者协调工作。播放的功能是MediaPlayer实现,而画面显示是依赖surfaceview实现。
2、设置WindowManager窗口
//Edited by mythou
  public void initWindow()
// 获取WindowManager
wm = (WindowManager) context.getApplicationContext().getSystemService(
"window");
// 设置LayoutParams(全局变量)相关参数
// wmParams = ((MyApplication)getApplication()).getMywmParams();
wmParams = new WindowManager.LayoutParams();
* 以下都是WindowManager.LayoutParams的相关属性 具体用途可参考SDK文档
wmParams.type = /*LayoutParams.TYPE_SYSTEM_ALERT | */LayoutParams.TYPE_SYSTEM_OVERLAY; // 设置window type
// 设置图片格式,效果为背景透明
wmParams.format = PixelFormat.TRANSPARENT;
// 设置Window flag
wmParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL
| LayoutParams.FLAG_NOT_FOCUSABLE
| LayoutParams.FLAG_LAYOUT_NO_LIMITS;
* 下面的flags属性的效果形同“锁定”。 悬浮窗不可触摸,不接受任何事件,同时不影响后面的事件响应。
* wmParams.flags=LayoutParams.FLAG_NOT_TOUCH_MODAL |
* LayoutParams.FLAG_NOT_FOCUSABLE | LayoutParams.FLAG_NOT_TOUCHABLE;
wmParams.gravity = Gravity.LEFT | Gravity.TOP; // 调整悬浮窗口至左上角
// 以屏幕左上角为原点,设置x、y初始值
currentDisplay = wm.getDefaultDisplay();
WIDTH = currentDisplay.getWidth();
HEIGHT = currentDisplay.getHeight();
wmParams.x = (WIDTH - VIEW_WIDTH) / 2;
wmParams.y = 0;
// 设置悬浮窗口长宽数据
wmParams.width = VIEW_WIDTH;
wmParams.height = VIEW_HEIGHT;
上面是使用WindowManager设置浮动窗口流程,跟我们上一篇界面的方法一致,具体不了解的朋友,可以看看我上一篇文章。
3、界面绑定画面
下面我们看看如何把我们的视频播放界面绑定到顶层显示View上面,上一篇已经介绍过,只需要调用addview方法即可。
//Edited by mythou
MyFloatView sFloatV
ViewGroup fV
//绑定XML配置的界面
fView = (ViewGroup) View.inflate(context, R.layout.main, null);
// 显示myFloatView图像
sFloatView = new MyFloatView(fView);
sFloatView.bindViewListener();
sFloatView.showLayoutView();
上面是通过配置一个XML来显示界面,XML界面里面定义了Surfaceview类,最后在FloatView里面的showLayoutView调用WindowManager的addView添加到窗口服务里面。
public void showLayoutView()
wm.addView(mlayoutView, wmParams);
上面就是大概的显示绑定流程,具体详细代码,请查看Demo里面的代码。这个Demo是在CSDN上面下载的,本来是想自己写一个,不过既然有开发者已经分享出来,我就没有重新自己写了,这个Demo我修改了一些错误,原版下载的,导入后会关联一个工程导致出错,修正了这个问题。下载我下面的代码,直接导入就可以使用。然后设置一下视频路径。
这只是一个很简单功能,视频路径也是写死了,只是让大家知道如何实现画中画功能。可以把这功能移植到我们的多媒体播放器上面实现视频的画中画播放。
测试Demo:
相关文章:
Edited by mythou
原创博文,转载请标明出处:
cavalry800528
浏览: 36865 次
ansjsun 写道抄袭的好。无所谓抄袭,自己理解就行。
抄袭的好。
没做过满汉全席,不要说自己会做饭?
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'安卓版YouTube推画中画 看视频搜节目不耽误
来源:搜狐IT
  【搜狐IT消息】据国外媒体报道,Google当地时间周一开始逐步发布Android版YouTube 5.0应用,其中一项重要功能是“画中画”。
  一名Google代表在接受媒体采访时表示,逐步发布Android版YouTube 5.0是有意而为之,并非提前泄露。
  Android版YouTube 5.0包含数项新功能,可以提供与YouTube相似的体验,有时甚至超过后者。Google证实,YouTube 5.0将于周二发布到Google Play应用商店,并将很快登陆iOS平台。
  除新标识和新界面外,Android版YouTube 5.0有三大新功能:
  ?画中画。用户可以将视频播放窗口缩小到屏幕右下角,在继续播放视频的同时切换频道或搜索节目。完成切换频道或搜索节目后,用户可以恢复或关闭视频播放窗口。
  ?浏览或播放视频播放列表。随着用户不断增长,播放列表成为YouTube最爱欢迎的功能之一。
  ?与在网站上一样,Android版YouTube 5.0用户可以对播放列表排序。(竹子)
(责任编辑:张娟)
&&&&&&</div
主演:黄晓明/陈乔恩/乔任梁/谢君豪/吕佳容/戚迹
主演:陈晓/陈妍希/张馨予/杨明娜/毛晓彤/孙耀琦
主演:陈键锋/李依晓/张迪/郑亦桐/张明明/何彦霓
主演:尚格?云顿/乔?弗拉尼甘/Bianca Bree
主演:艾斯?库珀/ 查宁?塔图姆/ 乔纳?希尔
baby14岁写真曝光
李冰冰向成龙撒娇争宠
李湘遭闺蜜曝光旧爱
美女模特教老板走秀
曝搬砖男神奇葩择偶观
柳岩被迫成赚钱工具
大屁小P虐心恋
匆匆那年大结局
乔杉遭粉丝骚扰
男闺蜜的尴尬初夜
客服热线:86-10-
客服邮箱:

我要回帖

更多关于 画中画 的文章

 

随机推荐