用 fold 累加列表
本课属于 Coddy Flutter 学习旅程的“状态管理”单元。第 8 课,共 27 课。
费用列表需要求总和。你可以通过循环逐项相加,但列表有一个方法可以直接完成这件事:fold。它会遍历列表,把一个值从一项传递到下一项:
double total = expenses.fold(0.0, (sum, e) => sum + e.amount);可以这样理解:从 0.0 开始。对于每笔费用 e,新的 sum 等于旧的 sum 加上 e.amount。遍历完列表后,最后的 sum 就是结果。对于 3.5 和 12,计算过程是 0.0,然后是 3.5,最后是 15.5。
这个函数必须返回新的总和。如果它只返回 e.amount,每一步都会忘记前一步的结果,“总和”就会变成最后一笔费用。
列表本身也可以改变:在 setState 中调用 expenses.add(...) 会再添加一项,下次构建时就会对新列表求和。
挑战
简单总计这一行总是显示 $0.00。请改为计算总额:
- 使用
expenses.fold设置total,将每笔支出的amount相加。
这一行已经显示 2 位小数,所以应显示为 Total: $15.50,添加零食后总额也会增加。
亲手试试
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class Expense {
Expense({required this.name, required this.amount});
final String name;
final double amount;
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final List<Expense> expenses = [
Expense(name: 'Coffee', amount: 3.5),
Expense(name: 'Lunch', amount: 12),
];
@override
Widget build(BuildContext context) {
double total = 0;
return Scaffold(
appBar: AppBar(title: const Text('Expenses')),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
for (final e in expenses) Text('${e.name}: \$${e.amount.toStringAsFixed(2)}'),
const SizedBox(height: 16),
Text('Total: \$${total.toStringAsFixed(2)}', style: const TextStyle(fontSize: 28)),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
setState(() {
expenses.add(Expense(name: 'Snack', amount: 2.25));
});
},
child: const Text('Add a snack'),
),
],
),
),
);
}
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
状态管理中的所有课
自己练习: Flutter 在线编译器