You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter应用中同时启用硬件键盘与软件键盘

强制Flutter应用实现软硬键盘共存

在配备硬件条码扫描器的Flutter应用中,系统默认会在硬件键盘连接时隐藏软件键盘,要实现软硬共存,需要分平台处理并结合Flutter代码调整:

Android 端配置与原生调用

  1. 修改AndroidManifest.xml
    在<activity>标签中添加软键盘模式配置,确保基础显示逻辑:

    <activity
        ...
        android:windowSoftInputMode="stateVisible|adjustResize">
    
  2. 通过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()
                  }
              }
          }
      }
      

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 19:43:13