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

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

右侧的ListWheel示意图

实现方案

核心逻辑分为三个部分:记录当前获得焦点的输入框、监听滚轮选中的数值、将数值同步到对应输入框。具体实现步骤如下:

  • 定义状态变量:包含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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 23:24:00