在 Flutter 中,通过封装 Dio 网络请求,可以将请求、响应处理和错误处理的逻辑集中在一起,减少代码重复并提升代码的可维护性。我们将在 RequestClient
类中创建一个通用的请求方法,支持 GET 和 POST 请求,并结合 EasyLoading 和 Lottie 动画,实现更好的用户体验。
步骤 1:创建 RequestConfig
基础配置类
首先定义请求的基本配置。RequestConfig
类负责存放 API 的 baseUrl
、连接超时时间 connectTimeout
和请求的成功状态码 successCode
等配置项。这样便于在项目中统一管理和调整这些参数。
arduino
class RequestConfig {
static const String baseUrl = "https://example.com/api"; // API 根地址
static const int connectTimeout = 5000; // 请求超时时间(毫秒)
static const int successCode = 200; // API 成功返回的状态码
}
步骤 2:初始化 Dio 实例
创建一个 RequestClient
类用于封装 Dio 的实例。这个类的构造函数中,我们会为 Dio 设置基础选项(如 baseUrl
和 connectTimeout
),并添加 pretty_dio_logger
插件,用于在控制台输出请求和响应的详细信息,方便调试。
kotlin
import 'package:dio/dio.dart';
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
class RequestClient {
late Dio _dio;
// 构造函数,配置 Dio 实例
RequestClient() {
_dio = Dio(
BaseOptions(
baseUrl: RequestConfig.baseUrl, // 请求的基础路径
connectTimeout: RequestConfig.connectTimeout, // 超时时间
),
);
// 添加日志拦截器,方便调试
_dio.interceptors.add(PrettyDioLogger(
requestHeader: true,
requestBody: true,
responseHeader: true,
));
}
}
步骤 3:封装通用的请求方法
在 RequestClient
类中创建一个 request
方法,该方法支持通用请求(GET 或 POST),接收请求路径、参数、以及是否显示加载动画等参数。方法的基本流程如下:
- 显示加载动画(可选)
- 发送请求并处理响应
- 捕获异常并调用错误处理函数
- 隐藏加载动画
以下是代码示例和逐步分析:
dart
Future<T?> request<T>(
String url, {
String method = "GET", // 请求方法,默认为 GET
Map<String, dynamic>? queryParameters, // 请求参数
data, // 请求数据(POST 时使用)
bool showLoading = true, // 是否显示加载动画
bool Function(ApiException)? onError, // 错误回调函数
Function()? onRequestComplete, // 请求完成后的回调函数
}) async {
// 1. 如果需要,显示加载动画
if (showLoading) {
Loading().showLoading();
}
try {
// 2. 发送请求
Response response = await _dio.request(
url,
queryParameters: queryParameters,
data: data,
options: Options(method: method),
);
// 3. 处理响应数据,返回给调用方
T? result = _handleResponse<T>(response);
onRequestComplete?.call(); // 调用请求完成后的回调
return result;
} catch (e) {
// 4. 捕获异常,处理错误
if (onError?.call(ApiException.from(e)) != true) {
handleException(ApiException.from(e));
}
} finally {
// 5. 隐藏加载动画
if (showLoading) {
Loading().dismissLoading();
}
}
return null;
}
-
参数说明:
url
:请求的路径。method
:请求方法("GET" 或 "POST")。queryParameters
:GET 请求的查询参数。data
:POST 请求的数据。showLoading
:是否显示加载动画。onError
:自定义的错误处理函数。onRequestComplete
:请求完成时的回调。
-
逻辑说明:
- 调用
_dio.request()
发送请求,GET 请求使用queryParameters
,POST 请求则使用data
。 - 如果请求成功,调用
_handleResponse
来解析响应。 - 请求失败时,将异常传递给自定义
onError
函数,如果未定义onError
,调用默认错误处理。
- 调用
步骤 4:处理响应数据
_handleResponse
方法用于处理 API 返回的数据,解析并返回特定数据类型(如 JSON 或 Model)。
kotlin
T _handleResponse<T>(Response response) {
if (response.statusCode == RequestConfig.successCode) {
// 假设返回的数据直接是 JSON,可根据实际情况解析
return response.data;
} else {
throw ApiException('Error: ${response.statusCode}');
}
}
注意 :这里根据 successCode
判断响应是否成功,并解析响应数据。如果返回的数据结构复杂,可在此方法中进一步解析。
步骤 5:错误处理
在 RequestClient
中添加 handleException
方法,用于捕获和处理错误,包括显示错误提示或执行自定义逻辑。
scss
void handleException(ApiException e) {
Loading().showErrorLoading(e.message); // 显示错误信息
}
- 错误提示 :使用
Loading().showErrorLoading()
显示错误信息。 - 异常捕获 :在
request
方法的catch
块中调用handleException
,确保所有异常被捕获并处理。
步骤 6:加载动画与 Lottie 动画集成
将 Loading
类中的 showLoading
方法改为使用 Lottie 动画展示,给用户更友好的加载体验。
javascript
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:lottie/lottie.dart';
class Loading {
void showLoading() {
EasyLoading.show(
indicator: Lottie.asset('assets/loading_animation.json'),
status: "加载中...",
);
}
void showErrorLoading(String message) {
EasyLoading.showError(message);
}
void dismissLoading() {
EasyLoading.dismiss();
}
}
总结与常见问题
通过以上步骤,我们实现了一个带有加载动画和错误处理的通用网络请求封装。在实际应用中,可以针对不同的业务需求和错误状态码进一步定制。
常见问题
-
EasyLoading.init()
未初始化- 确保在
main.dart
的runApp
之前调用EasyLoading.init()
。
- 确保在
-
请求超时或连接失败
- 调整
connectTimeout
或添加retry
机制,提升请求稳定性。
- 调整
-
Lottie 动画无法加载
- 检查动画文件路径是否正确,确保文件已经在项目中。
通过本文的讲解,你可以在 Flutter 项目中轻松实现网络请求的封装,并为用户提供更好的加载体验和错误提示。希望这篇文章对你有所帮助!