请求指导:Flutter中用Dio+Provider实现带Token的JSON转对象
没问题!我来一步步带你实现用Dio解析JSON到Users对象,同时结合Provider做状态管理。咱们按以下步骤来:
1. 先添加必要的依赖
首先打开你的pubspec.yaml,把dio和provider加进去,然后运行flutter pub get:
dependencies: flutter: sdk: flutter dio: ^5.4.0 # 用最新版本即可 provider: ^6.1.1
2. 配置Dio实例(自动携带Token)
为了方便全局复用Dio,并且自动在请求头里加Token,咱们可以创建一个单例的Dio工具类:
import 'package:dio/dio.dart'; class DioClient { final Dio _dio = Dio(); DioClient() { // 配置你的API基础地址 _dio.options.baseUrl = "https://your-api-base-url.com/"; // 添加拦截器,自动在请求头中携带Token _dio.interceptors.add(InterceptorsWrapper( onRequest: (options, handler) { // 这里替换成你的Token获取逻辑,比如从本地SharedPreferences读取 String? token = "your-auth-token-here"; if (token != null) { options.headers['Authorization'] = 'Bearer $token'; } return handler.next(options); }, onError: (DioException error, handler) { // 这里可以统一处理错误,比如Token过期时跳转登录页 return handler.next(error); }, )); } Dio get dio => _dio; }
3. 创建Provider状态管理类
接下来写一个UserProvider类,继承ChangeNotifier,用来管理用户数据的状态(加载中、错误、成功),同时封装API请求和JSON解析逻辑:
import 'package:flutter/material.dart'; import 'package:dio/dio.dart'; // 导入你之前定义的Users模型类 import 'your-users-model-file.dart'; class UserProvider extends ChangeNotifier { final DioClient _dioClient; // 状态变量 Users? _users; bool _isLoading = false; String? _errorMessage; // Getters供UI层读取状态 Users? get users => _users; bool get isLoading => _isLoading; String? get errorMessage => _errorMessage; UserProvider(this._dioClient); // 获取用户列表的核心方法 Future<void> fetchUsers() async { _isLoading = true; _errorMessage = null; notifyListeners(); // 更新加载状态 try { // 发起GET请求,替换成你的实际API接口路径 Response response = await _dioClient.dio.get("users"); // 直接用你写的usersFromJson方法解析返回的JSON _users = usersFromJson(response.data.toString()); } on DioException catch (e) { _errorMessage = e.response?.data['message'] ?? "请求失败,请稍后重试"; } catch (e) { _errorMessage = "未知错误"; } finally { _isLoading = false; notifyListeners(); // 更新最终状态 } } }
4. 在UI层使用Provider获取并展示数据
最后,咱们在Widget里使用Provider来获取数据,处理不同状态的UI展示:
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; // 导入你的Provider和模型类 import 'user_provider.dart'; import 'your-users-model-file.dart'; class UserListScreen extends StatelessWidget { const UserListScreen({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("用户列表")), body: Consumer<UserProvider>( builder: (context, provider, child) { if (provider.isLoading) { return const Center(child: CircularProgressIndicator()); } if (provider.errorMessage != null) { return Center(child: Text(provider.errorMessage!)); } if (provider.users?.data == null || provider.users!.data.isEmpty) { return const Center(child: Text("暂无用户数据")); } // 渲染用户列表 return ListView.builder( itemCount: provider.users!.data.length, itemBuilder: (context, index) { Datum user = provider.users!.data[index]; return ListTile( title: Text(user.name), subtitle: Text(user.email), trailing: Text(user.status), ); }, ); }, ), floatingActionButton: FloatingActionButton( onPressed: () { // 触发重新获取数据 context.read<UserProvider>().fetchUsers(); }, child: const Icon(Icons.refresh), ), ); } }
5. 在入口处注入Provider
别忘了在main.dart里把UserProvider和DioClient注入到Widget树中:
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'dio_client.dart'; import 'user_provider.dart'; import 'user_list_screen.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MultiProvider( providers: [ Provider(create: (_) => DioClient()), ChangeNotifierProxyProvider<DioClient, UserProvider>( create: (_) => UserProvider(DioClient()), update: (_, dioClient, userProvider) => UserProvider(dioClient), ), ], child: MaterialApp( title: 'Flutter Dio + Provider Demo', home: const UserListScreen(), ), ); } }
这样一套流程走下来,你就完成了用Dio请求带Token的API、将JSON解析为Users对象,同时用Provider管理状态的完整功能啦!
内容的提问来源于stack exchange,提问作者Qasem M. Zreaq
相关产品推荐
相关产品推荐

