Android WebView显示在Toolbar下方 全屏视频返回出现留白问题
问题根因
ConstraintLayout 子控件如果仅设置match_parent宽高、不配置任何约束,会默认定位到父布局左上角 (0,0) 坐标,直接导致WebView从屏幕最顶部开始绘制,覆盖在Toolbar下层。同时未适配系统窗口边距的情况下,WebView全屏视频播放切换时,系统状态栏的显示/隐藏状态变化会触发布局重新测量,很容易出现状态栏与Toolbar之间的白色空白块。
修复方案
1. 修正布局约束(必做)
首先给AppBarLayout添加id,为WebView配置完整的四边约束:顶部约束到AppBarLayout底部,左右和底部约束到父布局对应边缘。ConstraintLayout中推荐使用0dp(即match_constraint模式)配合约束实现撑满可用区域的效果,避免match_parent带来的布局测量冲突。
修正后的布局代码:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <com.google.android.material.appbar.AppBarLayout android:id="@+id/appbar" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/colorPrimary" android:minHeight="?attr/actionBarSize" android:theme="?attr/actionBarTheme" /> </com.google.android.material.appbar.AppBarLayout> <WebView android:id="@+id/webview" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintTop_toBottomOf="@id/appbar" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintBottom_toBottomOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
2. 修复全屏返回白块(可选,对应之前遇到的状态栏白块问题)
如果修正约束后仍存在全屏视频返回的白块问题,手动适配系统窗口Insets即可,不要依赖系统默认的布局调整逻辑。在Activity代码中做如下修改:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 关闭系统默认的内容边距适配,手动处理系统栏占位 getWindow().setDecorFitsSystemWindows(false); setContentView(R.layout.activity_main); Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); // 给AppBarLayout添加状态栏高度的顶部内边距,避免内容被状态栏遮挡 ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.appbar), (view, insets) -> { Insets statusBarInsets = insets.getInsets(WindowInsetsCompat.Type.statusBars()); view.setPadding( view.getPaddingLeft(), statusBarInsets.top, view.getPaddingRight(), view.getPaddingBottom() ); return insets; }); WebView myWebView = findViewById(R.id.webview); WebSettings webSettings = myWebView.getSettings(); webSettings.setJavaScriptEnabled(true); webSettings.setAllowFileAccess(true); webSettings.setAppCacheEnabled(true); myWebView.loadUrl("https://www.tn.com.ar"); myWebView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { return false; } }); myWebView.setWebChromeClient(new ChromeClient()); }
注意事项
- ConstraintLayout的直接子控件尽量不要使用
match_parent,优先用0dp+约束控制尺寸,减少测量冲突导致的布局错位 - 涉及全屏切换的场景(比如WebView全屏视频、全屏播放页),必须手动处理系统窗口Insets,不要依赖系统自动调整,否则大概率出现状态栏、导航栏相关的白块、内容遮挡问题
内容的提问来源于stack exchange,提问作者Mariano Pelizzari
相关产品推荐
相关产品推荐

