Flutter中使用Dio请求时如何将返回的JSON响应绑定到列表
Flutter Dio请求结果绑定列表实现方案
步骤1:创建对应结构的Dart实体类
为了保证类型安全,建议先将接口返回的JSON结构映射为Dart实体类,核心结构示例如下:
// 根响应实体 class OrderResponse { final bool success; final List<Order> data; final String message; OrderResponse({required this.success, required this.data, required this.message}); factory OrderResponse.fromJson(Map<String, dynamic> json) { var orderList = json['data'] as List; List<Order> orders = orderList.map((i) => Order.fromJson(i)).toList(); return OrderResponse( success: json['success'], data: orders, message: json['message'], ); } } // 订单实体 class Order { final int id; final String orderRefNo; final num orderTotal; final String orderDate; final Customer customer; final List<OrderInvoice> orderInvoice; // 其余字段按需添加 Order({required this.id, required this.orderRefNo, required this.orderTotal, required this.orderDate, required this.customer, required this.orderInvoice}); factory Order.fromJson(Map<String, dynamic> json) { var invoiceList = json['order_invoice'] as List; List<OrderInvoice> invoices = invoiceList.map((i) => OrderInvoice.fromJson(i)).toList(); return Order( id: json['id'], orderRefNo: json['order_ref_no'], orderTotal: json['order_total'], orderDate: json['order_date'], customer: Customer.fromJson(json['customer']), orderInvoice: invoices, ); } } // 客户实体 class Customer { final String firstName; final String lastName; final String mobile; // 其余字段按需添加 Customer({required this.firstName, required this.lastName, required this.mobile}); factory Customer.fromJson(Map<String, dynamic> json) { return Customer( firstName: json['first_name'], lastName: json['last_name'], mobile: json['mobile'], ); } } // 订单发票、商品等其余嵌套实体按需按照同样规则定义 class OrderInvoice { // 字段和fromJson方法同上 factory OrderInvoice.fromJson(Map<String, dynamic> json) => OrderInvoice(); }
你也可以直接用JSON转Dart的辅助工具生成完整实体类,避免手动编写出错。
步骤2:使用Dio发起请求并解析数据
在业务逻辑层发起网络请求,将响应结果解析为实体类列表,示例代码:
import 'package:dio/dio.dart'; List<Order> orderList = []; bool isLoading = false; Future<void> fetchOrderList() async { isLoading = true; try { Dio dio = Dio(); // 替换为你的实际接口地址 Response response = await dio.get('https://your-api-url.com/orders'); if (response.statusCode == 200) { OrderResponse orderResponse = OrderResponse.fromJson(response.data); if (orderResponse.success) { // 解析完成的订单列表赋值给全局/State变量 orderList = orderResponse.data; } else { // 处理接口返回的业务错误,比如弹出提示 print(orderResponse.message); } } } catch (e) { // 处理网络异常 print('请求失败:$e'); } finally { isLoading = false; // 如果是StatefulWidget,调用setState更新状态 // setState(() {}); } }
步骤3:将列表绑定到ListView组件
在UI层用列表组件渲染解析完成的订单数据,示例代码:
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('订单列表')), body: isLoading ? const Center(child: CircularProgressIndicator()) : orderList.isEmpty ? const Center(child: Text('暂无订单数据')) : ListView.builder( padding: const EdgeInsets.all(12), itemCount: orderList.length, itemBuilder: (context, index) { Order order = orderList[index]; return Card( margin: const EdgeInsets.only(bottom: 12), child: Padding( padding: const EdgeInsets.all(12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('订单号:${order.orderRefNo}', style: const TextStyle(fontWeight: FontWeight.bold)), const SizedBox(height: 4), Text('下单日期:${order.orderDate}'), const SizedBox(height: 4), Text('客户姓名:${order.customer.firstName} ${order.customer.lastName}'), const SizedBox(height: 4), Text('订单总价:¥${order.orderTotal}', style: const TextStyle(color: Colors.red)), // 如果需要展示发票/商品列表,可嵌套ExpansionTile和子ListView ], ), ), ); }, ), ); }
注意事项
- 首次进入页面时调用
fetchOrderList方法触发请求,比如在initState生命周期中调用 - 嵌套的
order_invoice商品列表如果需要展开展示,可使用ExpansionTile组件嵌套子列表实现 - 如果使用GetX、Riverpod等状态管理框架,可将订单列表和请求逻辑放到对应的状态管理类中,不用依赖StatefulWidget的setState更新
内容的提问来源于stack exchange,提问作者Parth Prajapati
相关产品推荐
相关产品推荐

