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

Flutter加载JSON数据到DataTable:按Tab分栏展示并转换时间戳

Flutter 实现分类标签页展示请假数据

1. 数据模型定义

先修复原JSON的语法错误(补全缺失的引号、逗号),然后定义用于解析数据的模型类:

class Leave {
  final String id;
  final String reason;
  final DateTime date;
  final String type;

  Leave({
    required this.id,
    required this.reason,
    required this.date,
    required this.type,
  });

  // 从JSON解析为模型对象,兼容ID为数字或字符串的情况
  factory Leave.fromJson(Map<String, dynamic> json) {
    return Leave(
      id: json['_id'].toString(),
      reason: json['reason'],
      date: DateTime.fromMillisecondsSinceEpoch(json['date']),
      type: json['type'],
    );
  }
}

2. 核心页面实现

使用DefaultTabController完成标签页管理,配合DataTable展示筛选后的请假数据,同时处理时间戳格式化:

import 'package:flutter/material.dart';

void main() => runApp(const LeaveRecordApp());

class LeaveRecordApp extends StatelessWidget {
  const LeaveRecordApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '请假记录',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const LeaveTabPage(),
    );
  }
}

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

  @override
  State<LeaveTabPage> createState() => _LeaveTabPageState();
}

class _LeaveTabPageState extends State<LeaveTabPage> {
  // 模拟接口返回的修正后JSON数据
  final Map<String, dynamic> rawLeaveData = {
    "status": "done",
    "msg": "Got all leaves",
    "data": [
      {
        "_id": "63b26e351bc7d25e5b7a1ebb",
        "reason": "发烧",
        "date": 1672511400000,
        "type": "tab1",
        "__v": 0
      },
      {
        "_id": "63b26fb91bc7d25e5b7a1ee8",
        "reason": "生病",
        "date": 1672511400000,
        "type": "tab1",
        "__v": 0
      },
      {
        "_id": "63b26dcc1bc7d25e5b7a1eb",
        "reason": "家庭事务",
        "date": 1672511400000,
        "type": "tab2",
        "__v": 0
      },
      {
        "_id": "63b26fcb1bc7d25e5b7a1ef3",
        "reason": "紧急请假",
        "date": 1672511400000,
        "type": "tab1",
        "__v": 0
      }
    ]
  };

  late List<Leave> allLeaveList;

  @override
  void initState() {
    super.initState();
    // 初始化时解析所有请假数据
    allLeaveList = (rawLeaveData['data'] as List)
        .map((item) => Leave.fromJson(item))
        .toList();
  }

  // 根据标签类型筛选数据
  List<Leave> _filterLeavesByType(String tabType) {
    return allLeaveList.where((leave) => leave.type == tabType).toList();
  }

  // 格式化日期为可读字符串
  String _formatDateTime(DateTime date) {
    return "${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')} ${date.hour.toString().padLeft(2, '0')}:${date.minute.toString().padLeft(2, '0')}";
  }

  // 构建DataTable组件
  Widget _buildLeaveTable(String tabType) {
    final filteredLeaves = _filterLeavesByType(tabType);
    return SingleChildScrollView(
      padding: const EdgeInsets.all(16),
      child: DataTable(
        border: TableBorder.all(),
        columns: const [
          DataColumn(label: Text('记录ID')),
          DataColumn(label: Text('请假原因')),
          DataColumn(label: Text('请假时间')),
        ],
        rows: filteredLeaves.map((leave) {
          return DataRow(cells: [
            DataCell(Text(leave.id)),
            DataCell(Text(leave.reason)),
            DataCell(Text(_formatDateTime(leave.date))),
          ]);
        }).toList(),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 2,
      child: Scaffold(
        appBar: AppBar(
          title: const Text('请假记录'),
          bottom: const TabBar(
            tabs: [
              Tab(text: '病假'),
              Tab(text: '事假'),
            ],
          ),
        ),
        body: TabBarView(
          children: [
            _buildLeaveTable('tab1'),
            _buildLeaveTable('tab2'),
          ],
        ),
      ),
    );
  }
}

关键实现要点

  • 数据解析:通过Leave.fromJson将JSON数据转换为强类型模型,同时直接把毫秒时间戳转为DateTime类型,简化后续格式化操作。
  • 标签页管理:用DefaultTabController实现标签页的切换逻辑,无需手动维护选中状态。
  • 数据筛选:通过_filterLeavesByType方法根据标签类型过滤对应的数据列表。
  • 日期格式化:_formatDateTime方法将DateTime转换为yyyy-MM-dd HH:mm的可读格式。
  • 滚动适配:用SingleChildScrollView包裹DataTable,避免数据过多时出现布局溢出问题。

内容的提问来源于stack exchange,提问作者Sakthivel k

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 16:55:41