好的,这个问题非常具体且关键。在 Android System WebView 的 138 和 139 版本(基于 Chromium 113)的上下文中,“清除软键盘占用的区域”通常意味着:在软键盘收起后,WebView 的布局或视口没有正确恢复,留下了一片空白区域(就像键盘仍然在那里一样)。
这个问题通常不是由用户主动“清除”的,而是开发者需要预防或编程解决的。以下是这个问题的原因和完整的解决方案。
问题根源
这个问题通常由以下原因引起:
- JavaScript 监听错误: 网页使用
window.onresize
来检测键盘状态,但在某些复杂交互下(特别是混合应用或快速切换焦点时),这个事件可能不可靠。 - 视口恢复失败: 这是一个经典的 Chromium Bug。在键盘收起后,WebView 的布局视口(Layout Viewport)或可视视口(Visual Viewport)的高度没有正确重置,导致
100vh
的区域仍然计算了键盘的高度。 - 第三方库或框架冲突: 某些用于处理键盘或输入的 JavaScript 库可能会干扰 WebView 默认的恢复行为。
解决方案
解决方案分为对开发者和对终端用户两种。
一、 给开发者的解决方案(治本)
如果你的网页或 Hybrid App 出现了此问题,你需要通过代码来修复。
方案 1:使用现代 CSS - 首选方案
这是最推荐、最根本的解决方案。使用 CSS 动态视口单位 来代替传统的 vh
。
-
将
height: 100vh
替换为height: 100dvh
dvh
(Dynamic Viewport Height)是专门为此场景设计的单位。它会自动排除正在显示的 UI(如软键盘)所占用的区域。- 在键盘弹出时,
100dvh
的高度就是屏幕高度减去键盘高度。 - 在键盘收起时,
100dvh
会自动恢复为整个屏幕高度。
示例:
/* 旧的、有问题的代码 */ .my-container {height: 100vh; }/* 新的、修复后的代码 */ .my-container {height: 100dvh; }
兼容性: 138+ 版本的 WebView(Chromium 113+)对此有良好的支持。对于更老的浏览器,可以考虑使用
@supports
进行回退。.my-container {height: 100vh; /* 回退方案 */height: 100dvh; /* 现代浏览器使用 */ }
方案 2:使用可靠的 JavaScript API 强制滚动复位
如果 CSS 方案无法完全解决,或者你需要更精确的控制,可以使用 visualViewport
API。
-
监听键盘收起事件并手动将页面滚动到一个合适的位置。
示例代码:
let isKeyboardShown = false;// 监听可视视口的变化(这是检测键盘最可靠的方式) window.visualViewport.addEventListener('resize', () => {// 如果可视视口高度变大,说明键盘很可能收起了if (window.visualViewport.height > previousHeight) {isKeyboardShown = false;// 关键修复:强制滚动到当前焦点元素或页面顶部// 有时需要一个小小的延时来确保布局已更新setTimeout(() => {// 方法1: 滚动到顶部window.scrollTo(0, 0);// 方法2: 如果知道特定元素,可以滚动到该元素// const activeElement = document.activeElement;// if (activeElement && activeElement.scrollIntoView) {// activeElement.scrollIntoView({block: 'nearest'});// }}, 50);} else {isKeyboardShown = true;} });// 监听输入框失焦事件也是一个很好的触发时机 document.addEventListener('focusout', () => {setTimeout(() => {// 再次检查是否还有活跃的输入框,如果没有,则可能是键盘收起了if (document.activeElement.tagName === 'BODY') {window.scrollTo(0, 0);}}, 100); });
二、 给终端用户的临时解决方法(治标)
如果用户遇到了这个问题,但无法等待开发者更新应用或网页,可以尝试以下临时性的解决方法:
-
重启 WebView 进程:
- 完全关闭出现问题的 App(从最近任务列表中划掉)。
- 重新打开 App。这是最有效且最简单的临时解决方案。
-
切换输入法:
- 有时特定输入法(如第三方输入法)与 WebView 的交互存在 Bug。尝试切换到系统自带的默认输入法(如 Gboard)。
-
旋转屏幕:
- 将手机从竖屏旋转到横屏,再转回竖屏。这个操作会强制 WebView 重新计算布局,通常可以清除占用的区域。
-
清除 WebView 数据(较麻烦):
- 打开手机 设置 -> 应用 -> Android System WebView。
- 进入 存储 -> 清除缓存 和 清除数据。
- 注意: 这可能会重置某些网页的登录状态和偏好设置。
-
更新或回滚 WebView:
- 前往 Google Play 商店,搜索 Android System WebView,确保它是最新版本。谷歌可能在后续版本中修复了此问题。
- 如果问题是在更新后出现的,可以尝试 卸载更新(在 WebView 的应用信息页面中有此选项),回退到系统自带的稳定版本。
总结
角色 | 解决方案 | 说明 |
---|---|---|
开发者 | 使用 height: 100dvh | 根本解决方案,符合现代 Web 标准。 |
开发者 | 使用 visualViewport API 手动控制 | 编程解决方案,用于复杂场景。 |
用户 | 重启 App | 最有效的临时方法,强制重置 WebView 状态。 |
用户 | 旋转屏幕/切换输入法 | 快速触发布局刷新的小技巧。 |
对于开发者来说,拥抱 dvh
等现代 CSS 单位是预防和解决此类布局问题的最佳实践。而 138 和 139 版本的 WebView 已经为这些新特性提供了稳定的支持。