您当前的位置: 首页 >  android

命运之手

暂无认证

  • 0浏览

    0关注

    747博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【Android】【全屏切换】优雅地实现播放器全屏切换

命运之手 发布时间:2020-08-18 11:29:07 ,浏览量:0

传统方法

  • 调整布局,隐藏多余的控件,让后将播放器设置为全屏大小
  • 新开一个Activity或PopupWindow来显示全屏播放器

传统方法的弊端

  • 布局复杂,播放器可能嵌套在Fragment或TabLayout等元素里面,难以调整为全屏
  • 布局调整代码常常极为繁琐,难以编写和阅读
  • 新开Activity或PopupWindow,实际是两个播放器对象,所有初始化工作要重新开始,并且需要一段时间来加载视频,本身Activity属于重量级组件,编写的代码比较多,而且流畅度也相对较差

优雅的解决方案

  • 我们平时加载的layout文件,其实不是Activity控件树的根节点,layout文件也是被放在一个ContentFrameLayout中,它实际也是个FrameLayout,我们暂把它称为ContentView
  • 由于Activity的ContentView是全屏的,而且是FrameLayout,我们只需直接将播放器加入到这个布局中,就可以实现全屏效果了,当然,屏幕还要翻转为横屏
  • 这样我们就有了一个非常简单的解决方案,将播放器从父容器中移除,然后再添加到ContentView中,退出全屏模式时,再从ContentView中移除,添加回父容器即可
  • 为了方便将播放器还原回父容器,我们可以用一个FrameLayout将播放器包裹起来,用FrameLayout作为播放器的父容器。用FrameLayout包裹最大的优势就是,添加移除控件很方便。将播放器从FrameLayout中移除后,FrameLayout仍然占据着播放器的空间,这样整个Activity布局仍然没有任何不变。如果直接将播放器放在LinearLayout等其它布局中,当播放器移除时,其它控件就会挤占播放器的空间,造成界面错乱

方案弊端

  • 有些播放器控件,不能正确处理屏幕翻转,尺寸改变,控件重新绑定父容器等情景
  • 但是这个弊端本质是播放器缺陷,就算使用其它方案,也会遇到这个问题
  • 对于这类播放器,我们可以重建一个播放器对象放到ContentView中,还原时再重建一个播放器放回FrameLayout
  • 采用重建对象的方式,我们需要保存播放进度,在全屏切换时还原进度

参考代码

以上已经给出了完整思路,已经足够大家自己动手完成整个功能 此处代码仅供参考,由于是自己的项目,大量使用了工具类,无法直接使用 如果有功能不清楚如何实现的,可以参考最后的源码


	@SuppressWarnings("all")
	public class StartActivity extends CommonActivity {
	
	    @BindView(R.id.view)
	    View view;
	
	    ViewGroup parent;
	    ViewGroup.LayoutParams layoutParams;
	
	    @Override
	    protected void create() {
	        setContentView(R.layout.activity_test);
	        Views.viewBinding(this, ctx);
	        requestAllPermissionWithCallback();
	    }
	
	    @Override
	    protected void onPermissionOk() {
	
	        //获得父容器和初始布局参数
	        parent = (ViewGroup) view.getParent();
	        layoutParams = view.getLayoutParams();
	
	        //全屏切换原理是将View从Parent中移除,添加到Window的ContentView中,并铺满ContentView
	        //Parent和ContentView都是FrameLayout,移除添加子节点,不会影响到其它控件位置
	
	        //屏幕切换不会立刻生效,因此要布局切换代码要延时执行,否则会导致布局计算错误,性能越差的机子需要的延时时间越长
	        //屏幕切换需要在AndroidManifest里面设置以下选项,否则窗口重建,会导致View移除添加代码报错
	        //android:configChanges="orientation|screenSize|keyboard|keyboardHidden"
	
	        onClick(view, () -> {
	            boolean horizontal = isHorizontalScreen();
	            //全屏
	            if (!horizontal) {
	                setFixedOrientation(Values.ORIENTATION.ORIENTATION_LANDSCAPE);
	                postLater(() -> {
	                    ViewGroup activityRootView = Views.getRootView(this);
	                    Views.detachFromParent(view);
	                    Views.attachAndFill(activityRootView, view);
	                    immersiveMode();
	                }, 200);
	            }
	            //还原
	            else {
	                setFixedOrientation(Values.ORIENTATION.ORIENTATION_PORTRAIT);
	                postLater(() -> {
	                    Views.detachFromParent(view);
	                    Views.attachAndLayout(parent, view, layoutParams);
	                    exitImmersiveMode(true);
	                }, 200);
	            }
	        });
	    }
	
	}

源码下载

安卓播放器全屏切换.zip

关注
打赏
1654938663
查看更多评论
立即登录/注册

微信扫码登录

0.0427s