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

Flutter Dio如何在Widget中展示onSendProgress上传进度

在Flutter中通过Dio和GetX展示上传进度

要把上传进度展示到Widget里,核心是把进度状态从API层传递到GetX控制器,再让Widget监听状态变化。具体步骤如下:

1. 修改API层,传递进度回调

修改CommonApiProvider的saveUserData方法,新增一个回调参数用于传递上传进度:

static Future saveUserData(Map params, {Function(int sent, int total)? onProgress}) async {
    try {
      var body = json.encode(params);
      final response = await _dio!.post("${globals.apiUrl}SaveUserData/",
          data: body, 
          onSendProgress: (int sent, int total) {
              print("$sent kb of data sent of total $total kb");
              // 把进度传递给外部回调
              onProgress?.call(sent, total);
      });
      if (response.statusCode == 200) {
        Map<String, String> d = Map<String, String>.from(response.data);
        return d;
      } else {
        return null;
      }
    } catch (exception) {
      return null;
    }
  }

2. 在GetX控制器中维护进度状态

在你的GetX控制器里,添加可观察的进度变量,并修改saveUserData方法,接收并更新进度:

class UserController extends GetxController {
  // 用可观察变量存储上传进度(百分比,0-1)
  final RxDouble uploadProgress = 0.0.obs;

  Future saveUserData() async{
    Map params = {
      // 你的参数内容
    };

    // 重置进度
    uploadProgress.value = 0.0;

    var res = await CommonApiProvider.saveUserData(params, onProgress: (sent, total) {
      if (total > 0) {
        // 计算百分比并更新状态
        uploadProgress.value = sent / total;
      }
    });
    
    // 上传完成后可以重置进度或者做后续处理
    uploadProgress.value = 0.0;
    // 处理返回结果...
  }
}

3. 在Widget中监听并展示进度

用GetX的Obx组件监听进度变化,展示进度条或文本:

class UploadScreen extends StatelessWidget {
  final UserController controller = Get.put(UserController());

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // 进度条
            Obx(() => LinearProgressIndicator(
              value: controller.uploadProgress.value,
              minHeight: 8,
              backgroundColor: Colors.grey[200],
              valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
            )),
            SizedBox(height: 16),
            // 进度文本
            Obx(() => Text(
              "上传进度: ${(controller.uploadProgress.value * 100).toStringAsFixed(1)}%",
              style: TextStyle(fontSize: 16),
            )),
            ElevatedButton(
              onPressed: () => controller.saveUserData(),
              child: Text("上传数据"),
            ),
          ],
        ),
      ),
    );
  }
}

这样,当你点击上传按钮时,进度条和文本会实时更新上传进度,完成后自动重置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 10:10:34