如何在 iOS 使用 Flutter 显示 “Done” 按钮以关闭键盘(简洁可复用的方法)
Source: Dev.to
在 Flutter 中构建以文本为主的界面时,最常被忽视的用户体验细节之一是用户如何关闭 iOS 键盘,尤其是在多行或数字输入框时。Android 键盘通常会提供可见的 “Done” 或 “Close” 按键,但 iOS 往往没有,导致用户只能点击输入框外部或尴尬地滚动才能收起键盘。
在 iOS 键盘上方添加自定义 “Done” 按钮的覆盖层非常简单。下面我们将探讨此功能为何重要、它如何提升文本输入的用户体验,以及如何使用 Flutter mixin 实现一个干净、可复用的解决方案。
为什么 iOS 需要自定义 “Done” 按钮?
- 多行输入框不会显示键盘关闭按钮。
- 数字键盘不包含回车/完成键。
- 底部弹窗常被键盘遮挡。
- 点击外部关闭键盘并不总是明显或可行。
- 键盘覆盖层可能隐藏关键的 CTA 按钮。
这些问题会在内容创作页面、表单、记笔记界面或任何需要输入多于几句话的场景中产生用户体验摩擦。自定义覆盖层在键盘正上方放置一个清晰、直观的 Done 按钮,让用户能够瞬间收起键盘。
使用 Mixin 的好处
- 无需重复样板代码。
- 保持 widget 树整洁。
- 可在多个页面之间复用。
- 自动管理覆盖层的插入和移除。
- 完全 iOS 安全(仅在
Platform.isIOS为 true 时运行)。
应用 Mixin
下面是一个最小示例,展示如何在页面中集成该 mixin。Mixin 会自动处理焦点变化和覆盖层管理。
// Example: TextInputPage with a reusable Done‑button mixin
class TextInputPage extends StatefulWidget {
@override
_TextInputPageState createState() => _TextInputPageState();
}
class _TextInputPageState extends State
with KeyboardDoneButtonMixin { // <-- your mixin
final TextEditingController _articleController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Article Editor')),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: TextField(
controller: _articleController,
focusNode: focusNode, // provided by the mixin
maxLines: null,
decoration: const InputDecoration(
hintText: 'Start typing...',
),
),
),
);
}
}
覆盖层行为
- 覆盖层激活 – 当文本框获取焦点时,mixin 会插入一个
OverlayEntry,位置正好在键盘上方。 - 动态定位 –
MediaQuery.of(context).viewInsets.bottom实时提供键盘高度,确保完美对齐。 - 安全移除 – 当焦点失去或用户点击 Done 按钮时,覆盖层会被干净地移除。
- 仅 iOS – 覆盖层在 Android、Web 或桌面平台上永不出现。
常见使用场景
- 聊天应用。
- 基于表单的工作流。
- 记笔记或内容创作页面。
扩展体验
因为覆盖层本质上是普通 widget,你可以:
- 应用自定义样式以匹配应用主题。
- 为覆盖层的进入和退出添加动画,以获得更精致的感觉。
在键盘上方放置一个 Done 按钮这样的小细节,能够显著提升 iOS 上的文本输入体验,尤其是在内容创作或表单驱动的工作流中。Mixin 方法让代码库保持清晰、可扩展、易维护,同时提供原生感的用户体验。