Flutter:点击输入框后如何关闭键盘的表情搜索建议?
解决方案
核心思路
iOS表情键盘的搜索建议属于系统键盘附加组件,Flutter默认API无法直接控制,需通过MethodChannel调用iOS原生代码,监听TextField聚焦事件,在再次聚焦时重置键盘输入状态,隐藏表情搜索栏。
步骤1:Flutter端实现
- 用
FocusNode监听TextField的聚焦状态 - 通过
MethodChannel向iOS原生发送重置键盘的指令
import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; class EmojiTextField extends StatefulWidget { const EmojiTextField({super.key}); @override State<EmojiTextField> createState() => _EmojiTextFieldState(); } class _EmojiTextFieldState extends State<EmojiTextField> { final FocusNode _focusNode = FocusNode(); final MethodChannel _channel = const MethodChannel('emoji_keyboard_handler'); @override void initState() { super.initState(); _focusNode.addListener(_onFocusChange); } void _onFocusChange() { if (_focusNode.hasFocus) { // 再次聚焦时调用原生代码重置键盘 _channel.invokeMethod('resetEmojiKeyboard'); } } @override void dispose() { _focusNode.removeListener(_onFocusChange); _focusNode.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return TextField( focusNode: _focusNode, keyboardType: TextInputType.text, decoration: const InputDecoration(hintText: '输入内容'), ); } }
步骤2:iOS原生端实现
在AppDelegate.swift中添加MethodChannel处理逻辑,重置键盘输入模式并隐藏搜索建议栏:
import UIKit import Flutter @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { let controller : FlutterViewController = window?.rootViewController as! FlutterViewController let channel = FlutterMethodChannel(name: "emoji_keyboard_handler", binaryMessenger: controller.binaryMessenger) channel.setMethodCallHandler { [weak self] (call: FlutterMethodCall, result: FlutterResult) in guard call.method == "resetEmojiKeyboard" else { result(FlutterMethodNotImplemented) return } self?.resetEmojiKeyboard() result(nil) } GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } private func resetEmojiKeyboard() { // 获取当前活跃的TextField guard let textField = UIResponder.currentFirstResponder() as? UITextField else { return } // 切换为默认文本输入模式,重置键盘状态 textField.keyboardType = .default textField.reloadInputViews() // iOS13+ 隐藏搜索建议栏 if #available(iOS 13.0, *) { textField.inputAssistantItem.leadingBarButtonGroups = [] textField.inputAssistantItem.trailingBarButtonGroups = [] } } } // 扩展UIResponder获取当前第一响应者 extension UIResponder { static func currentFirstResponder() -> UIResponder? { _currentFirstResponder = nil UIApplication.shared.sendAction(#selector(UIResponder.findFirstResponder(_:)), to: nil, from: nil, for: nil) return _currentFirstResponder } private static weak var _currentFirstResponder: UIResponder? @objc private func findFirstResponder(_ sender: Any) { UIResponder._currentFirstResponder = self } }
替代方案(纯Flutter,体验略逊)
若不想编写原生代码,可尝试在表情插入后,先主动失焦再重新聚焦,通过状态重置关闭搜索建议:
void _onEmojiSelected(String emoji) { // 插入表情到输入框 final text = _controller.text; _controller.text = text + emoji; // 失焦后延迟重新聚焦,重置键盘状态 _focusNode.unfocus(); Future.delayed(const Duration(milliseconds: 100), () { _focusNode.requestFocus(); }); }
该方案无需原生代码,但会有轻微键盘闪烁,适合快速迭代场景。
内容的提问来源于stack exchange,提问作者Burak AkşamYatmazSabahKalkmaz
相关产品推荐
相关产品推荐

