Flutter如何将ListWheelScrollView选中值填充到TextField

实现方案
核心逻辑分为三个部分:记录当前获得焦点的输入框、监听滚轮选中的数值、将数值同步到对应输入框。具体实现步骤如下:
- 定义状态变量:包含3个输入框对应的
TextEditingController、FocusNode,滚轮滚动控制器FixedExtentScrollController,以及记录当前激活输入框索引的标识 - 绑定输入框焦点监听:当任意输入框获得焦点时,更新当前激活输入框的索引值
- 绑定滚轮滚动监听:实时获取滚轮当前选中的数值
- 数值同步:当滚轮选中值变化时,将数值写入当前激活输入框的控制器中
完整示例代码
import 'package:flutter/material.dart'; class FormWithWheelPage extends StatefulWidget { const FormWithWheelPage({super.key}); @override State<FormWithWheelPage> createState() => _FormWithWheelPageState(); } class _FormWithWheelPageState extends State<FormWithWheelPage> { // 3个输入框的文本控制器 late final List<TextEditingController> _textControllers; // 3个输入框的焦点监听器 late final List<FocusNode> _focusNodes; // 记录当前激活的输入框索引,-1代表无激活输入框 int _activeTextFieldIndex = -1; // 滚轮滚动控制器 late final FixedExtentScrollController _wheelController; @override void initState() { super.initState(); // 初始化输入框控制器和焦点监听 _textControllers = List.generate(3, (_) => TextEditingController()); _focusNodes = List.generate(3, (index) => FocusNode() ..addListener(() { if (_focusNodes[index].hasFocus) { _activeTextFieldIndex = index; } })); // 初始化滚轮控制器,添加滚动监听 _wheelController = FixedExtentScrollController(); _wheelController.addListener(() { // 获取当前选中的滚轮项索引,对应数值为100+索引 int selectedValue = 100 + _wheelController.selectedItem; // 存在激活输入框时直接赋值 if (_activeTextFieldIndex != -1) { _textControllers[_activeTextFieldIndex].text = selectedValue.toString(); // 保留光标在文本末尾 _textControllers[_activeTextFieldIndex].selection = TextSelection.fromPosition( TextPosition(offset: _textControllers[_activeTextFieldIndex].text.length) ); } }); } @override void dispose() { // 销毁所有控制器和监听,避免内存泄漏 for (var c in _textControllers) { c.dispose(); } for (var n in _focusNodes) { n.dispose(); } _wheelController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: Row( children: [ // 左侧表单区域 Expanded( child: Padding( padding: const EdgeInsets.all(20), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: List.generate(3, (index) => Padding( padding: const EdgeInsets.symmetric(vertical: 10), child: _buildTextField(index), )), ), ), ), // 右侧滚轮区域 SizedBox( width: 100, child: _buildScrollWheel(context), ) ], ), ); } Widget _buildTextField(int index) { return TextField( controller: _textControllers[index], focusNode: _focusNodes[index], decoration: InputDecoration( labelText: '输入框${index + 1}', border: const OutlineInputBorder() ), keyboardType: TextInputType.number, ); } Widget _buildScrollWheel(BuildContext context) { List<Widget> list = _createSpeedTiles(); return ListWheelScrollView( controller: _wheelController, itemExtent: 30, perspective: 0.005, children: list, ); } List<Widget> _createSpeedTiles() { return [ for (var i = 100; i < 200; i += 1) ListTile( title: Text('$i', textAlign: TextAlign.center,), ) ]; } }
如果不需要滚动实时赋值,希望点击确认按钮后再填充数值,只需要把赋值逻辑从滚轮监听中移除,放到确认按钮的点击事件中即可。
内容的提问来源于stack exchange,提问作者SGoldwin
相关产品推荐
相关产品推荐

