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

Flutter中向普通类传函数参数:点击对话框按钮再执行函数的问题

问题解决:Flutter对话框触发传入函数的正确实现

问题根源

  1. 传递参数时直接执行了await database.deleteIncomeData(transaction),相当于把函数的执行结果传给了ShowDialog,而非函数本身
  2. 实例化ShowDialog后未调用showMyDialog()方法,导致对话框从未弹出

1. 调整对话框类(重命名避免内置方法冲突)

将类名改为ConfirmDialog(避免与Flutter内置showDialog方法冲突),同时适配异步函数类型:

import 'package:finsec/core/res/strings.dart';
import 'package:flutter/material.dart';
import '../../../../core/res/text_sizes.dart';
import '../../data/repositories/app_database.dart';

class ConfirmDialog {
  // 定义异步回调函数类型,适配数据库异步操作
  final Future<void> Function() onPressCallback;
  final BuildContext context;

  ConfirmDialog(this.onPressCallback, this.context);

  Future<String?> showMyDialog() async {
    return showDialog<String>(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text('Income Data'),
          content: SingleChildScrollView(
            child: ListBody(
              children: const <Widget>[
                Text(
                  'Do you want to apply these changes for future income transactions?',
                  style: TextStyle(fontSize: text_size_18),
                ),
                Text(
                  'Press NO if changes are only for this week income. Press Yes to apply changes to future weeks.',
                  style: TextStyle(fontSize: text_size_18),
                ),
              ],
            ),
          ),
          actions: <Widget>[
            TextButton(
              onPressed: () => Navigator.pop(context),
              child: const Text(cancelButton),
            ),
            TextButton(
              onPressed: () async {
                await onPressCallback(); // 等待异步操作完成
                Navigator.pop(context, successful);
              },
              child: const Text(noButton),
            ),
            TextButton(
              onPressed: () async {
                await onPressCallback();
                Navigator.pop(context, successful);
              },
              child: const Text(yesButton),
            ),
          ],
        );
      },
    );
  }
}

2. 调整Widget中的调用代码

传递函数引用而非执行结果,并调用showMyDialog()触发对话框:

CupertinoButton(
  padding: EdgeInsets.zero,
  onPressed: () async {
    // 用箭头函数包裹带参数的数据库操作,传递函数引用而非执行结果
    await ConfirmDialog(
      () => database.deleteIncomeData(transaction),
      context,
    ).showMyDialog(); // 必须调用此方法才会弹出对话框
  },
),

关键修改说明

  • 函数传递方式:() => database.deleteIncomeData(transaction)是传递匿名函数,只有用户点击对话框按钮时才会执行内部的数据库操作,避免了提前执行
  • 异步适配:将回调类型改为Future<void> Function(),并在按钮点击时用await等待数据库操作完成,保证逻辑顺序正确
  • 触发对话框:实例化类后必须调用showMyDialog(),否则对话框不会显示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 00:10:45