Flutter:如何累加API返回列表中Datum模型的sks字段值
Flutter 实现API返回数据中红色标记项的SKS累加
你可以按照以下步骤实现API数据中标记为红色的Datum.sks字段累加:
1. 确保API数据正确解析
先通过网络请求获取API数据并解析为SumValue模型(这里以http库为例,你也可以用Dio等其他网络库):
import 'dart:convert'; import 'package:http/http.dart' as http; Future<SumValue> fetchSumValue() async { final response = await http.get(Uri.parse('你的API接口地址')); if (response.statusCode == 200) { return SumValue.fromJson(jsonDecode(response.body)); } else { throw Exception('加载数据失败'); } }
2. 定义红色项的判断逻辑
根据你ListView中标记红色的业务规则,写一个判断函数,比如假设当nilaiHurufAkhir为'E'时该项标红:
bool isRedItem(Datum datum) { // 替换成你实际的红色标记条件 return datum.nilaiHurufAkhir == 'E'; }
3. 在异步流程中完成累加
因为API请求是异步操作,需要在数据返回后计算总和,再更新UI。以下是在StatefulWidget中的完整实现示例:
class SksSumPage extends StatefulWidget { const SksSumPage({super.key}); @override State<SksSumPage> createState() => _SksSumPageState(); } class _SksSumPageState extends State<SksSumPage> { late Future<SumValue> _sumValueFuture; int _redSksTotal = 0; bool isRedItem(Datum datum) { // 自定义红色项判断条件 return datum.nilaiHurufAkhir == 'E'; } @override void initState() { super.initState(); // 请求数据并计算总和 _sumValueFuture = fetchSumValue().then((sumValue) { // 方式1:用fold直接过滤累加 _redSksTotal = sumValue.data.fold(0, (prev, datum) { return isRedItem(datum) ? prev + datum.sks : prev; }); // 方式2:先过滤再累加(更直观) // _redSksTotal = sumValue.data.where(isRedItem).fold(0, (prev, datum) => prev + datum.sks); setState(() {}); return sumValue; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('红色项SKS总和')), body: FutureBuilder<SumValue>( future: _sumValueFuture, builder: (context, snapshot) { if (snapshot.hasData) { return Column( children: [ Padding( padding: const EdgeInsets.all(16.0), child: Text('红色项SKS总和: $_redSksTotal', style: const TextStyle(fontSize: 18)), ), Expanded( child: ListView.builder( itemCount: snapshot.data!.data.length, itemBuilder: (context, index) { final datum = snapshot.data!.data[index]; return ListTile( title: Text(datum.nmMk), subtitle: Text('SKS: ${datum.sks} | 成绩: ${datum.nilaiHurufAkhir}'), textColor: isRedItem(datum) ? Colors.red : null, // 标记红色文本 ); }, ), ), ], ); } else if (snapshot.hasError) { return Center(child: Text('加载失败: ${snapshot.error}')); } // 加载中 return const Center(child: CircularProgressIndicator()); }, ), ); } }
关键说明
- 异步处理:必须在API数据返回后(
then回调或FutureBuilder的snapshot.hasData分支)计算总和,避免空指针问题 - 过滤逻辑:
isRedItem函数是核心,一定要对应你ListView中标记红色的实际条件(比如特定状态、成绩等级等) - 两种累加方式:你可以选择直接在
fold里判断过滤,或者先用where筛选出红色项再累加,后者可读性更强
内容的提问来源于stack exchange,提问作者sharon
相关产品推荐
相关产品推荐

