Flutter实现TextField获焦显光标但不弹出键盘的方法
Flutter实现TextField获焦显示光标但不弹出键盘
我正在开发一个Flutter应用,需求是点击“Entrée”或“Sortie”按钮时,让“Nom” TextField获得焦点并显示光标,但不弹出屏幕键盘,以便通过扫码枪自动向获焦输入框输入文本。
项目配置
name: jtekt_mobile description: "A new Flutter project." publish_to: "none" version: 0.1.0 environment: sdk: ">=3.3.3 <4.0.0" dependencies: flutter: sdk: flutter dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^3.0.0 flutter: uses-material-design: true
当前代码
import 'package:flutter/material.dart'; import 'package:jtekt_mobile/models/mean_model.dart'; class Mean extends StatefulWidget { const Mean({super.key}); @override State<Mean> createState() => _MeanState(); } class _MeanState extends State<Mean> { bool isInOutSelected = false; bool isNameSelected = false; bool exitSelected = false; bool entrySelected = false; Color redColor = Colors.red; Color greenColor = Colors.green; Color greyColor = Colors.grey; List<MeanModel> meanList = []; final FocusNode nameFocusNode = FocusNode(); @override Widget build(BuildContext context) { return Column( children: [ Expanded( flex: 1, child: Container( color: Colors.white, child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ ElevatedButton( onPressed: entryButton, style: ElevatedButton.styleFrom( backgroundColor: !isInOutSelected || entrySelected ? greenColor : greyColor, ), child: const Text( "Entrée", style: TextStyle(color: Colors.white), ), ), ElevatedButton( onPressed: exitButton, style: ElevatedButton.styleFrom( backgroundColor: !isInOutSelected || exitSelected ? redColor : greyColor, ), child: const Text( "Sortie", style: TextStyle(color: Colors.white), ), ), ], ), ), ), if (isInOutSelected) Expanded( flex: 5, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisAlignment: MainAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.all(10), child: TextField( focusNode: nameFocusNode, decoration: InputDecoration( focusedBorder: OutlineInputBorder( borderSide: BorderSide( color: entrySelected ? greenColor : redColor, width: 4), ), border: const OutlineInputBorder(), labelText: ("Nom"), enabledBorder: OutlineInputBorder( borderSide: BorderSide( color: entrySelected ? greenColor : redColor, width: 2), ), ), ), ), const SizedBox(height: 20), if (isNameSelected) const Padding( padding: EdgeInsets.all(10), child: TextField( decoration: InputDecoration( border: const OutlineInputBorder(), labelText: ("Moyen"), enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.black, width: 2), ), ), ), ), const SizedBox(height: 20), Expanded( child: SingleChildScrollView( scrollDirection: Axis.vertical, child: Column( children: meanList .map((mean) => ListTile( title: Text(mean.username), subtitle: Text(mean.meanNumber), trailing: const Icon(Icons.delete), )) .toList(), ), ), ), if (isNameSelected) Center( child: ElevatedButton( onPressed: validation, style: ElevatedButton.styleFrom( backgroundColor: Colors.blue, ), child: const Text( "Valider", style: TextStyle(color: Colors.white), ), ), ), const SizedBox(height: 20), ], ), ), ], ); } void entryButton() { setState(() { isInOutSelected = true; entrySelected = true; exitSelected = false; }); nameFocusNode.requestFocus(); } void exitButton() { setState(() { isInOutSelected = true; exitSelected = true; entrySelected = false; }); nameFocusNode.requestFocus(); } void validation() {} }
已尝试的无效方案
- 调用
SystemChannels.textInput.invokeMethod('TextInput.hide') - 使用
FocusNode.unfocus() - 集成
input_with_keyboard_control库
可行解决方案
给目标TextField添加两个核心属性,即可实现获焦显示光标但不弹出软键盘的效果:
TextField( focusNode: nameFocusNode, keyboardType: TextInputType.none, // 禁用软键盘弹出 showCursor: true, // 确保获焦时显示光标 decoration: InputDecoration( focusedBorder: OutlineInputBorder( borderSide: BorderSide( color: entrySelected ? greenColor : redColor, width: 4), ), border: const OutlineInputBorder(), labelText: ("Nom"), enabledBorder: OutlineInputBorder( borderSide: BorderSide( color: entrySelected ? greenColor : redColor, width: 2), ), ), )
原理说明
TextInputType.none:Flutter官方提供的键盘类型,会告知系统不需要弹出软键盘,同时保留输入框的焦点状态和光标显示能力。showCursor: true:显式开启光标显示(默认获焦时会显示,显式设置可避免不同平台的行为差异)。
扫码枪模拟的是物理键盘输入,即使软键盘不弹出,获焦的输入框依然可以正常接收扫码枪的文本输入。
内容的提问来源于stack exchange,提问作者CosmosFutur
相关产品推荐
相关产品推荐

