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

Flutter实现条件触发Alert Dialog及解决弹窗无法关闭问题

Flutter TextField 非Double输入提示改为AlertDialog并修复弹窗关闭问题

关键修改点

  1. 替换文本提示为AlertDialog:移除原有的文本提示组件,改用showDialog触发弹窗展示错误信息
  2. 修复弹窗关闭问题:弹窗的Ok按钮必须调用Navigator.pop(context)才能关闭,之前的问题就是缺少这个关键调用

完整代码示例

import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text("Double Input Demo")),
        body: const DoubleInputField(),
      ),
    );
  }
}

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

  @override
  State<DoubleInputField> createState() => _DoubleInputFieldState();
}

class _DoubleInputFieldState extends State<DoubleInputField> {
  final TextEditingController _controller = TextEditingController();

  void _validateInput() {
    final input = _controller.text.trim();
    if (input.isEmpty) return;
    
    // 尝试解析输入为double类型
    final double? parsedValue = double.tryParse(input);
    if (parsedValue == null) {
      // 输入无效,弹出提示弹窗
      _showInvalidDialog();
    } else {
      // 输入有效,可执行后续业务逻辑
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text("有效输入:$parsedValue")),
      );
    }
  }

  void _showInvalidDialog() {
    showDialog(
      context: context,
      // 允许点击外部关闭弹窗(保持原有行为)
      barrierDismissible: true,
      builder: (BuildContext dialogContext) {
        return AlertDialog(
          title: const Text("输入错误"),
          content: const Text("Not A Double"),
          actions: [
            TextButton(
              onPressed: () {
                // 调用pop关闭弹窗,使用dialogContext确保正确导航
                Navigator.of(dialogContext).pop();
              },
              child: const Text("Ok"),
            ),
          ],
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          TextField(
            controller: _controller,
            keyboardType: const TextInputType.numberWithOptions(decimal: true),
            decoration: const InputDecoration(
              labelText: "请输入数字",
              border: OutlineInputBorder(),
            ),
          ),
          const SizedBox(height: 16),
          ElevatedButton(
            onPressed: _validateInput,
            child: const Text("验证输入"),
          ),
        ],
      ),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}

代码说明

  • 输入验证逻辑:通过double.tryParse()判断输入是否为有效双精度数字,返回null则触发错误弹窗
  • 弹窗关闭逻辑:在Ok按钮的点击回调中,必须调用Navigator.of(dialogContext).pop(),使用弹窗内部的dialogContext可以避免和页面上下文混淆,确保弹窗正确关闭
  • 可选配置:如果不需要点击外部关闭弹窗,可将barrierDismissible设为false

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 19:55:08