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

Flutter实现三TextField联动:填二自动算三并禁用的功能问题

实现三个联动TextField的解决方案

核心思路

通过三个TextEditingController监听输入变化,实时统计有效输入(非空且可转换为数字)的数量,根据数量判断哪个TextField需要自动计算值并禁用;当有效输入不足2个时,恢复所有输入框的可编辑状态并清空自动计算的内容。

完整代码示例

import 'package:flutter/material.dart';

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

  @override
  State<TripleTextFieldPage> createState() => _TripleTextFieldPageState();
}

class _TripleTextFieldPageState extends State<TripleTextFieldPage> {
  final TextEditingController _aController = TextEditingController();
  final TextEditingController _bController = TextEditingController();
  final TextEditingController _cController = TextEditingController();

  bool _isADisabled = false;
  bool _isBDisabled = false;
  bool _isCDisabled = false;

  @override
  void initState() {
    super.initState();
    // 给每个输入控制器添加监听,输入变化时触发计算逻辑
    _aController.addListener(_updateCalculation);
    _bController.addListener(_updateCalculation);
    _cController.addListener(_updateCalculation);
  }

  @override
  void dispose() {
    // 销毁控制器避免内存泄漏
    _aController.dispose();
    _bController.dispose();
    _cController.dispose();
    super.dispose();
  }

  void _updateCalculation() {
    // 解析输入值,无法转换为数字时返回null
    final double? a = double.tryParse(_aController.text.trim());
    final double? b = double.tryParse(_bController.text.trim());
    final double? c = double.tryParse(_cController.text.trim());

    // 统计有效输入的数量
    int validCount = 0;
    if (a != null) validCount++;
    if (b != null) validCount++;
    if (c != null) validCount++;

    // 先重置所有禁用状态
    setState(() {
      _isADisabled = false;
      _isBDisabled = false;
      _isCDisabled = false;
    });

    if (validCount == 2) {
      setState(() {
        if (a != null && b != null) {
          // A和B有效,计算C的乘积
          _cController.text = (a * b).toStringAsFixed(2);
          _isCDisabled = true;
        } else if (a != null && c != null) {
          // A和C有效,计算B(避免除以0)
          if (a != 0) {
            _bController.text = (c / a).toStringAsFixed(2);
          } else {
            _bController.text = '';
          }
          _isBDisabled = true;
        } else if (b != null && c != null) {
          // B和C有效,计算A(避免除以0)
          if (b != 0) {
            _aController.text = (c / b).toStringAsFixed(2);
          } else {
            _aController.text = '';
          }
          _isADisabled = true;
        }
      });
    } else if (validCount < 2) {
      // 有效输入不足2个,清空自动计算的内容
      setState(() {
        if (_isADisabled) _aController.text = '';
        if (_isBDisabled) _bController.text = '';
        if (_isCDisabled) _cController.text = '';
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('联动TextField示例')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            TextField(
              controller: _aController,
              enabled: !_isADisabled,
              keyboardType: TextInputType.numberWithOptions(decimal: true),
              decoration: const InputDecoration(labelText: '输入A'),
            ),
            const SizedBox(height: 16),
            TextField(
              controller: _bController,
              enabled: !_isBDisabled,
              keyboardType: TextInputType.numberWithOptions(decimal: true),
              decoration: const InputDecoration(labelText: '输入B'),
            ),
            const SizedBox(height: 16),
            TextField(
              controller: _cController,
              enabled: !_isCDisabled,
              keyboardType: TextInputType.numberWithOptions(decimal: true),
              decoration: const InputDecoration(labelText: '输入C'),
            ),
          ],
        ),
      ),
    );
  }
}

关键细节说明

  • 统一监听逻辑:用addListener替代每个TextField的onChanged,避免重复代码,确保输入变化时统一触发计算。
  • 容错处理:使用double.tryParse处理非数字输入,避免崩溃;计算除法时判断除数不为0,防止出现无效数值。
  • 状态重置:每次计算前先重置禁用状态,确保有效输入数量变化时,能正确恢复输入框的可编辑性。
  • 精度控制:用toStringAsFixed(2)保留两位小数,可根据需求调整精度。

内容的提问来源于stack exchange,提问作者Seyit Kılıç

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 12:15:02