Android Studio如何让布局常驻ViewPager顶部 解决SurfaceView滑动被遮挡问题
问题根因
你遇到的遮挡问题是SurfaceView的特性导致的:SurfaceView的渲染Surface独立于Android常规View的视图树,默认Surface层级位于宿主窗口下层、仅高于窗口背景。常规View的bringToFront()方法只会调整视图树内的绘制顺序,无法影响独立Surface的z轴排序,ViewPager滑动触发页面重绘时,就会出现SurfaceView被新渲染的ViewPager页面覆盖的问题。
解决方案
方案1:修改SurfaceView的z轴层级(改动最小)
在SurfaceView初始化后、添加到父容器前,设置Surface的z轴顺序,该配置必须在Surface创建前生效:
previewDisplayView = new SurfaceView(this); // 新增以下配置 // 若需要Surface盖在所有窗口内容之上用这个 previewDisplayView.setZOrderOnTop(true); // 若只需要盖在普通View之上、不需要盖在其他视频Surface/弹窗之上,用下面这行替代上一行 // previewDisplayView.setZOrderMediaOverlay(true); // 如需支持透明背景加这行 previewDisplayView.getHolder().setFormat(PixelFormat.TRANSLUCENT); setupPreviewDisplayView();
方案2:替换为TextureView(兼容性更好)
如果不需要SurfaceView的性能优势,替换为TextureView即可,TextureView遵循常规View的层级规则,支持bringToFront()、translationZ等常规层级调整方法,不会出现层级异常问题。
兜底方案:监听ViewPager切换主动刷新层级
如果调整后仍偶发遮挡,可以给ViewPager添加页面切换监听,每次切换完成后主动刷新上层布局的层级:
videosViewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { @Override public void onPageScrollStateChanged(int state) { super.onPageScrollStateChanged(state); // 滑动停止后刷新层级 if (state == ViewPager2.SCROLL_STATE_IDLE) { View previewLayout = findViewById(R.id.preview_display_layout); previewLayout.bringToFront(); previewLayout.requestLayout(); } } });
布局优化建议
根布局优先使用FrameLayout,FrameLayout的子视图层级由添加顺序决定,将你的预览布局放在ViewPager之后声明,天然就拥有更高的视图树层级,进一步降低被覆盖的概率。
内容的提问来源于stack exchange,提问作者Vmir
相关产品推荐
相关产品推荐

