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

Flutter中API获取SVG后UI未自动更新问题求助

Flutter弹窗中更新State后UI不刷新的解决方法

问题根源

你的弹窗是通过StatefulBuilder创建的,它拥有独立的状态更新方法setStateDialog,但你在handleQrCodePaymentMethod中调用的是页面级的setState——这个方法只会触发页面的UI重建,不会更新弹窗内部的状态,导致弹窗UI无法自动刷新。

解决方案

将状态变量和请求方法移到StatefulBuilder内部,使用弹窗专属的setStateDialog更新状态,同时添加加载状态避免重复点击:

1. 调整弹窗内部的状态与请求方法

在_addFunds的StatefulBuilder builder函数内定义状态变量和请求方法:

Future<bool> _addFunds(BuildContext context) {
  bool isDepositInfoVisible = false;

  return showDialog<bool>(
    barrierDismissible: false,
    context: context,
    builder: (BuildContext context) {
      return StatefulBuilder(
        builder: (BuildContext context, StateSetter setStateDialog) {
          // 把状态变量移到弹窗内部
          bool isLoading = false;
          String? paymentQrCode;

          // 弹窗内部的请求方法,使用setStateDialog更新状态
          void handleQrCodePaymentMethod() async {
            setStateDialog(() {
              isLoading = true;
            });
            try {
              final authService = AuthenticationService();
              final dioClient = DioClient(authService);
              ApiClient apiClient =
                  ApiClient(baseUrl: Env.apiUrl, dioClient: dioClient);

              String endpoint = 'funds/generate-payment';

              Map<String, String> data = {
                'paymentType': 'qrCode',
                'iban': _iban,
                'bic': _swift,
                'bank': _bankName,
                'paymentIdentification': widget.accountId,
                'amount': _priceController.text,
                'currency': _selectedFundsCurrency.toString(),
              };

              var response = await apiClient.performPostRequest(endpoint, data);

              if (response['response'] == 'OK') {
                setStateDialog(() {
                  paymentQrCode = response['qrCode'];
                  isLoading = false;
                });
              }
            } catch (e) {
              print('Catch error: $e');
              setStateDialog(() {
                isLoading = false;
              });
            }
          }

          return AlertDialog(
            // ... 原有弹窗内容
            // 替换原有的按钮/SVG区域
            child: isLoading
              ? const CircularProgressIndicator()
              : paymentQrCode == null
                ? ElevatedButton(
                    onPressed: handleQrCodePaymentMethod,
                    style: ElevatedButton.styleFrom(
                      minimumSize: const Size(200, 50),
                      padding: const EdgeInsets.symmetric(vertical: 14.0, horizontal: 20.0),
                      backgroundColor: const Color.fromRGBO(0, 122, 255, 1),
                      foregroundColor: Colors.white,
                    ),
                    child: Text(
                      AppLocalizations.of(context)!.detailsGenerateButton,
                    ),
                  )
                : Padding(
                    padding: const EdgeInsets.only(bottom: 65.0),
                    child: SvgPicture.string(
                      paymentQrCode.toString(),
                      key: ValueKey<String>(paymentQrCode.toString()),
                      height: 330,
                      width: 330,
                    ),
                  )
          );
        },
      );
    },
  );
}

关键修改点说明

  • 将paymentQrCode和新增的isLoading状态变量移到StatefulBuilder内部,确保它们属于弹窗的状态上下文。
  • 使用setStateDialog替代页面的setState,直接触发弹窗的UI重建。
  • 添加isLoading状态,在API请求过程中显示加载指示器,请求完成后更新状态,解决之前加载 spinner 无限转动的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 08:09:57