You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter实现类安卓最近通话列表UI:无额外包优化代码

优化Flutter分组交易列表UI实现

原实现的核心问题在于直接在ListView.builder中维护临时列表和状态,容易因多次触发build导致数据混乱,且渲染逻辑冗余。更合理的方式是先对数据按日期分组,再基于分组后的数据构建UI,逻辑更清晰且性能更优。

优化步骤与代码实现

1. 数据分组逻辑

先将原始交易数据按日期分组,把同一日期的交易归为一组。可以在initState中完成分组(如果是StatefulWidget),避免每次build重复计算:

// 按日期分组的函数
Map<String, List<Trans>> groupTransByDate(List<Trans> data) {
  final Map<String, List<Trans>> groupedData = {};
  final dateFormat = DateFormat('yMMMMd');
  
  for (final trans in data) {
    final dateStr = dateFormat.format(trans.date);
    groupedData.putIfAbsent(dateStr, () => []).add(trans);
  }
  
  return groupedData;
}

2. 完整Widget实现

使用分组后的数据构建列表,每个列表项对应一个日期分组,包含日期标题和该日期的所有交易项容器:

class TransListScreen extends StatefulWidget {
  const TransListScreen({super.key});

  @override
  State<TransListScreen> createState() => _TransListScreenState();
}

class _TransListScreenState extends State<TransListScreen> {
  late final Map<String, List<Trans>> _groupedTrans;

  @override
  void initState() {
    super.initState();
    // 初始化时完成数据分组
    _groupedTrans = groupTransByDate(data);
  }

  Map<String, List<Trans>> groupTransByDate(List<Trans> data) {
    final Map<String, List<Trans>> groupedData = {};
    final dateFormat = DateFormat('yMMMMd');
    
    for (final trans in data) {
      final dateStr = dateFormat.format(trans.date);
      groupedData.putIfAbsent(dateStr, () => []).add(trans);
    }
    
    return groupedData;
  }

  @override
  Widget build(BuildContext context) {
    // 将分组的Map转换为列表,方便ListView.builder遍历
    final groupedList = _groupedTrans.entries.toList();
    
    return SafeArea(
      child: Scaffold(
        body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: ListView.builder(
            itemCount: groupedList.length,
            itemBuilder: (context, index) {
              final entry = groupedList[index];
              final dateTitle = entry.key;
              final transList = entry.value;
              
              return Column(
                children: [
                  // 日期标题容器
                  Container(
                    height: 40,
                    alignment: Alignment.center,
                    child: Text(dateTitle),
                  ),
                  // 交易项容器
                  Container(
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(8.0),
                      color: Colors.grey.shade300,
                    ),
                    child: Column(
                      children: List.generate(
                        transList.length,
                        (tileIndex) => CustomTransTileWidget(
                          showDivider: tileIndex != transList.length - 1,
                          trans: transList[tileIndex],
                        ),
                      ),
                    ),
                  ),
                  // 分组之间的间隔
                  const SizedBox(height: 8),
                ],
              );
            },
          ),
        ),
      ),
    );
  }
}

3. 原Trans类与测试数据保持不变

class Trans {
  String id;
  double amount;
  String title;
  bool isExpense;
  DateTime date;
  
  Trans({
    required this.id,
    required this.title,
    this.isExpense = false,
    required this.amount,
    required this.date,
  });
}

List<Trans> data = [
  Trans(id: '1', title: 'Food', amount: 100.0, date: DateTime(2023,08,01)),
  Trans(id: '2', title: 'Food', amount: 130.0, date: DateTime(2023,08,01)),
  Trans(id: '3', title: 'Food', amount: 150.0, date: DateTime(2023,08,01)),
  Trans(id: '4', title: 'Food', amount: 300.0, date: DateTime(2023,08,02), isExpense: false),
  Trans(id: '5', title: 'Food', amount: 200.0, date: DateTime(2023,08,02)),
];

优化优势

  • 逻辑清晰:先分组再渲染,避免在itemBuilder中维护复杂的临时状态
  • 性能更优:仅在初始化时分组一次,不会因build重复计算;ListView的itemCount是分组数量,减少不必要的组件渲染
  • 可维护性强:分组逻辑独立,后续修改分组规则仅需调整groupTransByDate函数

内容的提问来源于stack exchange,提问作者Irfan Ganatra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 20:12:47