关于 capacitor-keyboard
用于排查和配置 Capacitor 应用键盘行为的开发技能,适合处理输入界面布局问题。内容包括 iOS 调整模式、Android inset 及聊天输入栏等自定义布局。
主要功能
- 01iOS 键盘调整模式
- 02Android 键盘 inset 指南
- 03键盘感知的自定义定位
- 04键盘事件与插件排查
适用场景
- 01确保聚焦字段保持可见
- 02定位聊天输入栏
- 03修复键盘上方空隙
- 04排查事件重复或未触发
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ cap-go/ capgo-skills --skill capacitor-keyboard安装后在 Claude Code 中输入/capacitor-keyboard确认已加载。
附带文件metadata.json
详细介绍
Capacitor 中的键盘处理
适用场景
在以下情况触发:
- 聚焦的输入框被键盘遮挡,或页面意外滚动
- 聊天输入框 / 固定页脚无法贴合键盘
- 键盘上方出现白色或黑色条带(Android 15+ 的 edge-to-edge、iOS 背景)
- 键盘打开时,
100vh/dvh布局发生塌陷 - iOS 放大输入框,或 QuickType / 配件栏显示异常
- 键盘事件始终不触发或触发两次
不适用于:
- 刘海 / Home 指示器 / 状态栏内边距:
safe-area-handling - Ionic
ion-input、ion-footer样式:ionic-design - 标签、焦点顺序、屏幕阅读器:
capacitor-accessibility
平台模型(关键决策)
| iOS | Android | |
|---|---|---|
| 谁调整大小 | 插件,根据 resize 模式 | OS + WebView;忽略 resize 配置 |
| 事件 | 动画前触发 keyboardWillShow,动画后触发 keyboardDidShow | Will / Did 几乎同时触发 |
| JS 控制 | setResizeMode、getResizeMode、setScroll、setStyle、setAccessoryBarVisible(仅限 iPhone) | show()(仅限 Android)、hide() |
iOS resize 模式(KeyboardResize 枚举):
| 模式 | 效果 | 适用场景 |
|---|---|---|
native(默认) | 整个 WebView 缩小;vh 单位变化 | 普通 Web 应用;最简单 |
body | 仅 <body> 高度变化;vh 不变 | 依赖稳定 vh 的布局 |
ionic | 仅 ion-app 调整大小 | 仅适用于 Ionic Framework 应用 |
none | 不调整大小;使用键盘高度定位 | 自定义聊天 UI、需要完全控制时 |
工作流
- 检查:
capacitor.config.*中的plugins.Keyboard、@capacitor/keyboard版本(8.0.4+ 包含 iOS 26 和 Android SystemBars 修复)、是否使用 Ionic、@capacitor/status-bar/ SystemBars 配置,以及出问题页面的 CSS(position: fixed、100vh)。 - 在设备上重现问题(模拟器通常会使用硬件键盘:iOS Simulator -> I/O -> Keyboard -> Toggle Software Keyboard)。
- 根据表格选择 iOS resize 模式;在配置中设置,而不是在运行时设置,除非某个屏幕需要不同模式。
- 单独修复 Android(见下文)。
- 验证。
配置
// capacitor.config.ts
import { KeyboardResize, KeyboardStyle } from '@capacitor/keyboard';
plugins: {
Keyboard: {
resize: KeyboardResize.Body, // iOS only
style: KeyboardStyle.Default, // iOS only; JSON value is "DARK" | "LIGHT" | "DEFAULT"
// resizeOnFullScreen: omit on Capacitor 8+ (SystemBars handles insets; see Android notes)
autoBackdropColor: 'auto', // iOS, 8.0.4+: 'off' (default) | 'auto' | 'dom'
},
},
JSON 配置中的字符串值,style 使用大写("DARK"),resize 使用小写("body")。
自定义定位(resize: none 或聊天 UI)
import { Capacitor } from '@capacitor/core';
import { Keyboard } from '@capacitor/keyboard';
if (Capacitor.isNativePlatform()) {
Keyboard.addListener('keyboardWillShow', ({ keyboardHeight }) => {
document.documentElement.style.setProperty('--kb', `${keyboardHeight}px`);
});
Keyboard.addListener('keyboardWillHide', () => {
document.documentElement.style.setProperty('--kb', '0px');
});
}
.composer {
position: fixed;
inset-inline: 0;
bottom: max(var(--kb, 0px), env(safe-area-inset-bottom));
}
使用 max(),而不是 +:键盘弹出时,Home 指示器内边距已经被覆盖。
Android 说明
- Android 15+(targetSdk 35)强制采用 edge-to-edge;Android 16(targetSdk 36,Capacitor 8 默认)移除了退出选项。WebView 现在会在系统栏下方绘制,因此必须处理键盘内边距。
@capacitor/keyboard7.0.2 修复了 Android 15+ 键盘上方的白色空白,8.0.3 修复了与 SystemBars 核心插件的交互问题。请先更新插件,再编写变通方案。 resizeOnFullScreen: true是 Capacitor <= 7 中用于全屏 / 覆盖状态栏的变通方案。在 Capacitor 8+ 中,SystemBars 核心插件会处理 IME 内边距;除非SystemBars.insetsHandling为disable,否则会记录You should omit `Keyboard.resizeOnFullScreen` in your `capacitor.config.json`. Other values can lead to unexpected behavior.。请移除此项。- 不要添加
android:windowSoftInputMode="adjustPan"来修复遮挡问题;它会平移整个窗口并破坏固定页眉。模板中未包含此项(默认采用 resize 行为)。 env(keyboard-inset-height)和interactive-widgetviewport meta 是 Chromium 功能;依赖它们之前,请在目标 Android System WebView 版本上进行测试,且绝不要在 iOS 上使用。
iOS 注意事项
- 计算后的
font-size小于 16px 时,iOS 会在输入框获得焦点时缩放页面。请为输入框设置font-size: 16px(或更大);不要全局禁用用户缩放(maximum-scale=1),否则会损害无障碍体验。 setAccessoryBarVisible({ isVisible: false })会隐藏 iPhone 上的上一项/下一项/完成栏;对 iPad 无效。setScroll({ isDisabled: true })可阻止键盘打开时 WebView 滚动视图回弹;自定义布局时请搭配resize: none使用。- iOS 26 键盘回归问题和 iPad 妙控键盘上的黑色 QuickType 栏问题已在
@capacitor/keyboard8.0.4 中修复。如果键盘后方出现黑色/白色条带,请设置autoBackdropColor: 'auto'(使用配置中的backgroundColor,否则使用 DOM body 背景),或设置为'dom'。
验证
- 运行
npx cap sync,并在实体 iPhone 和 Android 15+/16 设备上运行。 - 对每个表单屏幕:聚焦第一个和最后一个输入框;确保聚焦字段保持可见、页脚贴在键盘上方、键盘上方没有空隙;键盘打开时旋转设备,确保布局保持正常。
- 通过滑动/返回按钮关闭键盘:确认
keyboardWillHide触发,且--kb恢复为 0。 - iOS:确认聚焦时不会缩放;辅助栏状态与设计一致。
- 检查版本:
npm ls @capacitor/keyboard @capacitor/core。
错误处理
| 症状/消息 | 原因 | 修复方法 |
|---|---|---|
"Keyboard" plugin is not implemented on web 或 "Keyboard.setAccessoryBarVisible()" is not implemented on android | 插件/方法在该平台不可用 | 使用 Capacitor.getPlatform() === 'ios' 进行保护 |
iOS 上 show() 无效 | show() 仅适用于 Android | 改为通过用户手势聚焦输入框 |
| 键盘关闭后页脚悬在中间(Android) | 键盘无动画隐藏时,WebView 高度未重置 | 更新到 @capacitor/keyboard 8.0.4+ |
| Android 15+ 上键盘上方出现白色条带 | 全屏显示边缘到边缘的内边距 + 旧版插件 | 更新插件(7.0.2+ / 8.0.3+);在 Capacitor 8 上移除 resizeOnFullScreen |
Logcat SystemBars: You should omit `Keyboard.resizeOnFullScreen` ... | 旧版配置与 SystemBars 的内边距处理冲突 | 从配置中删除 resizeOnFullScreen |
基于 vh 的屏幕在 iOS 上缩小 | resize: native 会改变视口 | 改为 body 或 none |
| Ionic 内容跳动两次 | resize: native/body 加上 Ionic 自身的处理 | 使用 resize: 'ionic' |
| 导航后监听器触发两次 | 每次页面挂载都会添加监听器,但从未移除 | 保留返回的句柄,并在卸载时执行 await handle.remove() |
| 使用硬件键盘时 iPad 上出现黑色 QuickType 栏 | 8.0.4 之前版本的插件缺陷 | 更新插件 |
资源
评论
支持 Markdown