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

Flutter中如何实现填写一个输入框后自动填充其他关联输入框的值

实现方案

该功能无需引入第三方插件,基于Flutter原生能力即可实现。核心逻辑是通过输入框控制器的监听事件触发联动换算,同时增加更新锁避免循环触发更新。

完整可运行代码
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() => runApp(const UnitConverterApp());

class UnitConverterApp extends StatelessWidget {
  const UnitConverterApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '单位换算',
      home: Scaffold(
        appBar: AppBar(title: const Text('长度单位换算')),
        body: const LengthConverter(),
      ),
    );
  }
}

class LengthConverter extends StatefulWidget {
  const LengthConverter({super.key});

  @override
  State<LengthConverter> createState() => _LengthConverterState();
}

class _LengthConverterState extends State<LengthConverter> {
  // 定义三个输入框的控制器
  final _meterController = TextEditingController();
  final _cmController = TextEditingController();
  final _feetController = TextEditingController();
  // 更新锁,避免循环触发监听
  bool _isUpdating = false;

  @override
  void initState() {
    super.initState();
    // 给每个控制器添加监听
    _meterController.addListener(() => _onInputChanged(UnitType.meter));
    _cmController.addListener(() => _onInputChanged(UnitType.centimeter));
    _feetController.addListener(() => _onInputChanged(UnitType.feet));
  }

  // 输入变更触发的换算逻辑
  void _onInputChanged(UnitType activeType) {
    if (_isUpdating) return;
    _isUpdating = true;

    try {
      double? inputValue;
      // 读取当前激活输入框的值
      switch (activeType) {
        case UnitType.meter:
          inputValue = double.tryParse(_meterController.text.trim());
          break;
        case UnitType.centimeter:
          inputValue = double.tryParse(_cmController.text.trim());
          break;
        case UnitType.feet:
          inputValue = double.tryParse(_feetController.text.trim());
          break;
      }

      // 输入为空或者非法时清空所有输入框
      if (inputValue == null) {
        _meterController.clear();
        _cmController.clear();
        _feetController.clear();
        _isUpdating = false;
        return;
      }

      // 统一转换为米作为基准值
      double meterValue;
      switch (activeType) {
        case UnitType.meter:
          meterValue = inputValue;
          break;
        case UnitType.centimeter:
          meterValue = inputValue / 100;
          break;
        case UnitType.feet:
          meterValue = inputValue / 3.28084;
          break;
      }

      // 更新其他输入框的值
      if (activeType != UnitType.meter) {
        _meterController.text = meterValue.toStringAsFixed(4);
      }
      if (activeType != UnitType.centimeter) {
        _cmController.text = (meterValue * 100).toStringAsFixed(2);
      }
      if (activeType != UnitType.feet) {
        _feetController.text = (meterValue * 3.28084).toStringAsFixed(4);
      }
    } finally {
      _isUpdating = false;
    }
  }

  @override
  void dispose() {
    // 销毁控制器,避免内存泄漏
    _meterController.dispose();
    _cmController.dispose();
    _feetController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        children: [
          _buildInputItem('米 (m)', _meterController),
          const SizedBox(height: 16),
          _buildInputItem('厘米 (cm)', _cmController),
          const SizedBox(height: 16),
          _buildInputItem('英尺 (ft)', _feetController),
        ],
      ),
    );
  }

  // 复用输入框组件
  Widget _buildInputItem(String label, TextEditingController controller) {
    return TextField(
      controller: controller,
      keyboardType: const TextInputType.numberWithOptions(decimal: true),
      inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d*'))],
      decoration: InputDecoration(
        labelText: label,
        border: const OutlineInputBorder(),
      ),
    );
  }
}

// 单位类型枚举
enum UnitType {
  meter,
  centimeter,
  feet,
}
注意事项
  • 如果需要新增换算单位,只需新增对应的TextEditingController、UnitType枚举值,补充换算逻辑和输入框组件即可
  • 代码中已经添加了输入校验,仅允许输入数字和小数点,可根据需求修改inputFormatters调整校验规则
  • toStringAsFixed用来控制输出的小数位数,可根据实际精度需求调整
  • 如果项目中已经使用状态管理框架(如Provider、Bloc等),也可以把换算逻辑放到状态层实现,适配更复杂的业务场景

内容的提问来源于stack exchange,提问作者MNBLabs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 14:45:02