如何在Flutter应用中同时启用硬件键盘与软件键盘
强制Flutter应用实现软硬键盘共存
在配备硬件条码扫描器的Flutter应用中,系统默认会在硬件键盘连接时隐藏软件键盘,要实现软硬共存,需要分平台处理并结合Flutter代码调整:
Android 端配置与原生调用
修改AndroidManifest.xml
在<activity>标签中添加软键盘模式配置,确保基础显示逻辑:<activity ... android:windowSoftInputMode="stateVisible|adjustResize">通过MethodChannel强制唤起软键盘
由于硬件键盘连接时系统会自动隐藏软键盘,需通过原生代码强制显示:- 在Android项目的MainActivity中添加MethodChannel实现:
import android.content.Context import android.view.inputmethod.InputMethodManager import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel class MainActivity : FlutterActivity() { private val CHANNEL = "keyboard_utils" override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> when (call.method) { "showSoftKeyboard" -> { val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager val view = currentFocus ?: window.decorView.rootView imm.showSoftInput(view, InputMethodManager.SHOW_FORCED) result.success(null) } else -> result.notImplemented() } } } }
- 在Android项目的MainActivity中添加MethodChannel实现:
iOS 端原生调用
iOS系统默认不会在硬件键盘连接时自动显示软键盘,同样通过MethodChannel实现强制唤起:
- 在iOS项目的AppDelegate中添加MethodChannel实现:
import UIKit import Flutter @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { private let CHANNEL = "keyboard_utils" override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { let controller : FlutterViewController = window?.rootViewController as! FlutterViewController let channel = FlutterMethodChannel(name: CHANNEL, binaryMessenger: controller.binaryMessenger) channel.setMethodCallHandler { [weak self] call, result in guard let self = self else { return } switch call.method { case "showSoftKeyboard": guard let view = UIApplication.shared.keyWindow?.rootViewController?.view else { result.error("VIEW_NOT_FOUND", "No view found to attach keyboard", nil) return } view.becomeFirstResponder() // 强制唤起软键盘 if let inputVC = self.getTextInputViewController() { inputVC.showKeyboard(true) } result.success(nil) default: result.notImplemented() } } GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } private func getTextInputViewController() -> UIInputViewController? { for window in UIApplication.shared.windows { if let inputVC = window.rootViewController as? UIInputViewController { return inputVC } } return nil } }
Flutter 端调用逻辑
在Flutter代码中,通过MethodChannel调用原生方法,在需要显示软键盘的时机(如TextField获取焦点后)触发:
import 'package:flutter/services.dart'; class KeyboardHelper { static const MethodChannel _channel = MethodChannel('keyboard_utils'); /// 强制显示软件键盘 static Future<void> forceShowSoftKeyboard() async { try { await _channel.invokeMethod('showSoftKeyboard'); } on PlatformException catch (e) { print('唤起软键盘失败: ${e.message}'); } } } // 使用示例 class MyTextField extends StatefulWidget { @override State<MyTextField> createState() => _MyTextFieldState(); } class _MyTextFieldState extends State<MyTextField> { final FocusNode _focusNode = FocusNode(); @override void initState() { super.initState(); _focusNode.addListener(() { if (_focusNode.hasFocus) { // 获取焦点后强制唤起软键盘 KeyboardHelper.forceShowSoftKeyboard(); } }); } @override void dispose() { _focusNode.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return TextField( focusNode: _focusNode, decoration: const InputDecoration(hintText: '输入内容'), ); } }
额外注意事项
- 确保你的TextField或输入组件已正确设置
focusNode,这样在获取焦点时才能触发软键盘唤起逻辑。 - Android端部分设备可能需要开启“允许同时使用软硬键盘”的系统设置,但通过上述代码可绕过手动设置强制唤起。
内容的提问来源于stack exchange,提问作者SonOfGillas
相关产品推荐
相关产品推荐

