Flutter 中 Dio + Freezed + Retrofit + Json 的组合体验如何?❤
Flutter 中 Dio + Freezed + Retrofit + Json 的组合体验
在 Flutter 开发中,API 请求和数据处理是一个常见的需求。结合 Dio
、Freezed
、Retrofit
和 Json Serializable
可以带来非常高效的开发体验。以下是一个完整的示例,展示了如何使用这些库来处理分页 API 响应。
前提条件
Dio
:用于 HTTP 请求Retrofit
:生成所有的请求Freezed
:生成用于处理的数据模型Json Serializable
:生成 JSON 解析逻辑GetIt
:依赖注入Build Runner
和其他生成器
在 pubspec.yaml
中添加依赖项
dependencies:
flutter:
sdk: flutter
dio: ^4.0.0
retrofit: ^2.0.0
freezed_annotation: ^0.14.0
json_annotation: ^4.0.1
get_it: ^7.2.0
dev_dependencies:
build_runner: ^2.0.4
freezed: ^0.14.0
json_serializable: ^4.0.1
后端返回分页响应
假设后端返回一个分页响应,包含所有分页数据和请求的数据模型,结构如下:
{
"docs": [
{
"id": 1,
"title": "Post Title",
"content": "Post Content"
}
],
"total": 10,
"page": 1,
"limit": 10
}
创建基础类
docs
数组可以是任何类型,因此创建一个 PaginatedResponse
类作为基础类。
// paginated_response.dart
import 'package:json_annotation/json_annotation.dart';
part 'paginated_response.g.dart';
@freezed
abstract class PaginatedResponse<T> with _$PaginatedResponse<T> {
factory PaginatedResponse({
required List<T> docs,
required int total,
required int page,
required int limit,
}) = _PaginatedResponse;
factory PaginatedResponse.fromJson(Map<String, dynamic> json) =>
_$PaginatedResponseFromJson(json);
}
生成代码:
flutter pub run build_runner build
创建实际的数据模型
例如,创建一个 Post
数据模型。
// post.dart
import 'package:json_annotation/json_annotation.dart';
part 'post.g.dart';
@freezed
abstract class Post with _$Post {
factory Post({
required int id,
required String title,
required String content,
}) = _Post;
factory Post.fromJson(Map<String, dynamic> json) => _$PostFromJson(json);
}
生成代码:
flutter pub run build_runner build
创建 API
使用 Dio
+ Retrofit
创建 API。
// retrofit_api.dart
import 'package:dio/dio.dart';
import 'package:retrofit/retrofit.dart';
import 'package:your_app/models/paginated_response.dart';
import 'package:your_app/models/post.dart';
part 'retrofit_api.g.dart';
@RetrofitInterface(baseUrl: "https://your-api-endpoint.com")
interface ApiService {
@GET("/posts")
Future<PaginatedResponse<Post>> getPosts(
@Query("page") int page,
@Query("limit") int limit,
);
}
生成代码:
flutter pub run build_runner build
配置依赖注入
在 GetIt
中注册 ApiService
。
// dependency_injection.dart
import 'package:dio/dio.dart';
import 'package:get_it/get_it.dart';
import 'package:retrofit/retrofit.dart';
import 'retrofit_api.dart';
final getIt = GetIt.instance;
void setupDependencies() {
final dio = Dio();
final retrofit = Retrofit.builder()
.baseUrl("https://your-api-endpoint.com")
.converterFactory(StandardConverters.create())
.client(dio)
.build();
getIt.registerSingleton<Retrofit>(retrofit);
getIt.registerFactory<ApiService>(() => retrofit.create(ApiService()));
}
在应用的入口文件(如 main.dart
)中调用 setupDependencies
。
// main.dart
import 'package:flutter/material.dart';
import 'dependency_injection.dart';
void main() {
setupDependencies();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter App'),
),
body: Center(
child: Text('Hello, Flutter!'),
),
),
);
}
}
使用 API
在你的 Flutter 组件中使用 ApiService
获取数据。
// posts_page.dart
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'dependency_injection.dart';
import 'retrofit_api.dart';
class PostsPage extends StatefulWidget {
@override
_PostsPageState createState() => _PostsPageState();
}
class _PostsPageState extends State<PostsPage> {
late ApiService apiService;
late Future<PaginatedResponse<Post>> postsFuture;
@override
void initState() {
super.initState();
setupDependencies();
apiService = getIt.get<ApiService>();
postsFuture = apiService.getPosts(page: 1, limit: 10);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Posts'),
),
body: FutureBuilder<PaginatedResponse<Post>>(
future: postsFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
} else {
final posts = snapshot.data?.docs ?? [];
return ListView.builder(
itemCount: posts.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(posts[index].title),
subtitle: Text(posts[index].content),
);
},
);
}
},
),
);
}
}
总结
通过这种方式,你可以:
- 拥有灵活的数据请求模型
- 只需要一个命令来生成数据、请求等
- 拥有所有这些库带来的好处,如代码生成、类型安全、易于维护和扩展等
希望这个示例能帮助你在 Flutter 项目中更好地使用 Dio
、Freezed
、Retrofit
和 Json Serializable
!
更多关于Flutter 中 Dio + Freezed + Retrofit + Json 的组合体验如何?❤的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter 中 Dio + Freezed + Retrofit + Json 的组合体验如何?❤的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter开发中,结合Dio、Freezed、Retrofit和Json进行网络请求和数据处理的体验非常流畅且高效。这种组合不仅简化了API调用的复杂性,还提高了代码的可读性和可维护性。以下是一个简要的代码示例,展示如何使用这些库进行网络请求和数据解析。
1. 添加依赖
首先,在pubspec.yaml
文件中添加所需的依赖:
dependencies:
flutter:
sdk: flutter
dio: ^4.0.0 # 确保使用最新版本
retrofit: ^2.0.0 # 确保使用最新版本
freezed_annotation: ^0.14.0 # 确保使用最新版本
json_annotation: ^4.0.1 # 确保使用最新版本
build_runner: ^2.0.4 # 用于生成代码
2. 定义数据模型
使用Freezed和Json库定义不可变的数据模型,并自动生成fromJson
和toJson
方法。
// models/user.dart
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:json_annotation/json_annotation.dart';
part 'user.freezed.dart';
part 'user.g.dart';
@freezed
abstract class User with _$User {
factory User({
required String id,
required String name,
required String email,
}) = _User;
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
}
// 生成代码
// flutter pub run build_runner build --delete-conflicting-outputs
3. 定义API接口
使用Retrofit定义API接口,结合Dio进行网络请求。
// api/user_api.dart
import 'package:dio/dio.dart';
import 'package:retrofit/retrofit.dart';
import 'package:your_app/models/user.dart';
part 'user_api.g.dart';
@RetrofitInterface(baseUrl: "https://api.example.com/")
interface UserApi {
@GET("/users/{id}")
Future<User> getUserById(@Path("id") String id);
}
// 生成代码
// flutter pub run build_runner build --delete-conflicting-outputs
4. 配置Retrofit和Dio
在主应用或某个初始化位置配置Retrofit和Dio实例。
// main.dart
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:retrofit/retrofit.dart';
import 'api/user_api.dart';
import 'models/user.dart';
void main() async {
final dio = Dio();
final retrofit = Retrofit.builder()
.baseUrl("https://api.example.com/")
.build();
final userApi = retrofit.create<UserApi>(dio);
runApp(MyApp(userApi));
}
class MyApp extends StatelessWidget {
final UserApi userApi;
MyApp(this.userApi);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Flutter Demo')),
body: Center(
child: FutureBuilder<User>(
future: userApi.getUserById("1"),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
final user = snapshot.data!;
return Text('User: ${user.name} (${user.email})');
}
} else {
return CircularProgressIndicator();
}
},
),
),
),
);
}
}
总结
通过以上步骤,我们使用Flutter中的Dio、Freezed、Retrofit和Json库实现了一个简单的网络请求和数据解析流程。这种组合不仅简化了代码,还提高了开发效率和代码质量。Freezed提供了不可变的数据模型,Retrofit简化了API调用,而Dio则是一个强大的HTTP客户端库,Json库则帮助我们轻松地进行数据序列化和反序列化。这种组合在现代Flutter开发中非常流行,值得一试。