Flutter 2.5.0稳定版获取TextFormField选中文本失效问题咨询
问题根因
Flutter 2.5稳定版确实调整了Material组件库按钮的默认交互逻辑,新增requestFocusOnPress属性且默认值为true,点击按钮时会主动请求焦点,导致TextFormField失去焦点,输入框失焦后选中状态会被清空,因此selection.start和selection.end均返回-1。
修复方案
有两种常用实现方式:
- 方式1:关闭按钮的焦点请求行为
给ElevatedButton添加requestFocusOnPress: false属性,点击按钮时不会抢占输入框焦点,选中状态可正常保留,修改后按钮代码如下:ElevatedButton( onPressed: _onPressed, requestFocusOnPress: false, child: Text("do something"), ) - 方式2:提前缓存选中状态
若业务逻辑需要点击按钮后输入框失焦,可以监听输入框控制器的变化,提前缓存有效选中范围,取值时直接读取缓存即可,完整修改代码如下:import 'package:flutter/material.dart'; class Play extends StatefulWidget { const Play({Key? key}) : super(key: key); @override _PlayState createState() => _PlayState(); } class _PlayState extends State<Play> { final TextEditingController _controller = TextEditingController(); final FocusNode _node = FocusNode(); // 存储最新有效选中范围 TextSelection _latestSelection = TextSelection.collapsed(offset: 0); @override void initState() { super.initState(); _controller.addListener(() { if (_controller.selection.start >= 0) { _latestSelection = _controller.selection; } }); } void _onPressed() { print("selection.start: ${_latestSelection.start}"); print("selection.end: ${_latestSelection.end}"); // 如需提取选中文本可使用以下代码 // final selectedText = _latestSelection.textInside(_controller.text); } @override Widget build(BuildContext context) { return Scaffold( body: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ TextFormField( focusNode: _node, controller: _controller, ), ElevatedButton( onPressed: _onPressed, child: const Text("do something"), ), ], ), ); } }
内容的提问来源于stack exchange,提问作者Herry
相关产品推荐
相关产品推荐

