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

如何在Flutter中使用Dio、Retrofit和Riverpod实现POST API请求?

Flutter中用Dio+Retrofit+Riverpod实现POST请求完整流程

1. 安装依赖

在pubspec.yaml中添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  dio: ^5.4.0+1
  retrofit: ^4.0.3
  flutter_riverpod: ^2.4.9
  json_annotation: ^4.8.1

dev_dependencies:
  flutter_test:
    sdk: flutter
  build_runner: ^2.4.8
  retrofit_generator: ^7.0.8
  json_serializable: ^6.7.1

添加后执行flutter pub get安装依赖。

2. 定义数据模型

创建models/login_model.dart,定义请求和响应的实体类,配合json_serializable实现序列化:

import 'package:json_annotation/json_annotation.dart';

part 'login_model.g.dart';

@JsonSerializable()
class LoginRequest {
  final String username;
  final String password;

  LoginRequest({required this.username, required this.password});

  factory LoginRequest.fromJson(Map<String, dynamic> json) => _$LoginRequestFromJson(json);
  Map<String, dynamic> toJson() => _$LoginRequestToJson(this);
}

@JsonSerializable()
class LoginResponse {
  final String token;
  final String userId;

  LoginResponse({required this.token, required this.userId});

  factory LoginResponse.fromJson(Map<String, dynamic> json) => _$LoginResponseFromJson(json);
  Map<String, dynamic> toJson() => _$LoginResponseToJson(this);
}

执行命令生成序列化代码:

flutter pub run build_runner build

3. 定义Retrofit API接口

创建services/api_service.dart,定义POST请求接口:

import 'package:dio/dio.dart';
import 'package:retrofit/retrofit.dart';
import '../models/login_model.dart';

part 'api_service.g.dart';

@RestApi(baseUrl: "https://your-api-base-url.com/")
abstract class ApiService {
  factory ApiService(Dio dio) = _ApiService;

  @POST("auth/login")
  Future<LoginResponse> login(@Body() LoginRequest request);
}

再次执行flutter pub run build_runner build生成Retrofit实现代码。

4. Riverpod状态管理

创建providers/auth_provider.dart,封装API实例和登录状态逻辑:

import 'package:dio/dio.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../services/api_service.dart';
import '../models/login_model.dart';

// 提供ApiService实例
final apiServiceProvider = Provider<ApiService>((ref) {
  final dio = Dio();
  // 可添加拦截器、超时配置等
  dio.interceptors.add(LogInterceptor(responseBody: true, requestBody: true));
  return ApiService(dio);
});

// 登录状态枚举
enum LoginState { initial, loading, success, error }

// 登录状态管理Notifier
class LoginNotifier extends StateNotifier<({LoginState state, String? message, LoginResponse? data})> {
  final ApiService apiService;

  LoginNotifier(this.apiService) : super((state: LoginState.initial, message: null, data: null));

  Future<void> login(String username, String password) async {
    state = (state: LoginState.loading, message: null, data: null);
    try {
      final response = await apiService.login(LoginRequest(username: username, password: password));
      state = (state: LoginState.success, message: "登录成功", data: response);
    } on DioException catch (e) {
      state = (state: LoginState.error, message: e.response?.data?["message"] ?? "登录失败", data: null);
    } catch (e) {
      state = (state: LoginState.error, message: "未知错误", data: null);
    }
  }
}

// 提供LoginNotifier实例
final loginNotifierProvider = StateNotifierProvider<LoginNotifier, ({LoginState state, String? message, LoginResponse? data})>((ref) {
  return LoginNotifier(ref.watch(apiServiceProvider));
});

5. UI层实现

创建pages/login_page.dart,实现登录页面并调用逻辑:

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../providers/auth_provider.dart';

class LoginPage extends ConsumerStatefulWidget {
  const LoginPage({super.key});

  @override
  ConsumerState<LoginPage> createState() => _LoginPageState();
}

class _LoginPageState extends ConsumerState<LoginPage> {
  final _usernameController = TextEditingController();
  final _passwordController = TextEditingController();

  @override
  void dispose() {
    _usernameController.dispose();
    _passwordController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final loginState = ref.watch(loginNotifierProvider);

    return Scaffold(
      appBar: AppBar(title: const Text("登录")),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            TextField(
              controller: _usernameController,
              decoration: const InputDecoration(labelText: "用户名"),
            ),
            TextField(
              controller: _passwordController,
              decoration: const InputDecoration(labelText: "密码"),
              obscureText: true,
            ),
            const SizedBox(height: 20),
            if (loginState.state == LoginState.loading)
              const CircularProgressIndicator()
            else
              ElevatedButton(
                onPressed: () {
                  ref.read(loginNotifierProvider.notifier).login(
                    _usernameController.text.trim(),
                    _passwordController.text.trim(),
                  );
                },
                child: const Text("登录"),
              ),
            if (loginState.message != null)
              Padding(
                padding: const EdgeInsets.only(top: 16),
                child: Text(
                  loginState.message!,
                  style: TextStyle(color: loginState.state == LoginState.success ? Colors.green : Colors.red),
                ),
              ),
          ],
        ),
      ),
    );
  }
}

关键说明

  • Retrofit通过注解生成API实现代码,简化Dio的调用逻辑
  • Riverpod的StateNotifier负责处理异步请求的状态变化(加载、成功、失败)
  • UI层通过Consumer监听状态变化,动态更新界面

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 14:45:31