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

Flutter Web构建后DataTable组件显示灰色问题求助

Flutter Web部署GitHub后DataTable构建版本显示灰色问题排查

将Flutter Web应用部署到GitHub后,应用整体可正常运行,但DataTable组件在构建版本中显示为灰色,调试模式下显示正常。以下是组件代码、浏览器错误信息,请求协助排查原因。

截图:DataTable显示灰色的效果


组件代码

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../constants/theme.dart';
import '../providers/general.dart';

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

  @override
  State<DashboardTable> createState() => _DashboardTableState();
}

class _DashboardTableState extends State<DashboardTable> {
  List<bool> selected = List<bool>.generate(100, (int index) => false);
  bool ascending = false;

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: context.watch<General>().dati,
      builder: (context, snapshot) {
        if (snapshot.hasData &&
            !context.watch<General>().isLoading &&
            !context.watch<General>().isEmpty) {
          return ConstrainedBox(
              constraints: BoxConstraints(
                minWidth: double.infinity,
                maxHeight: MediaQuery.of(context).size.height - 170,
              ),
              child: Expanded(
                child: Container(
                  decoration: BoxDecoration(
                      color: mainColor50,
                      borderRadius: BorderRadius.circular(8),
                      border: Border.all(color: mainColor700, width: 1)),
                  child: ClipRRect(
                    borderRadius: BorderRadius.circular(8),
                    child: SingleChildScrollView(
                      child: DataTable(
                          dataRowMinHeight: 40,
                          dataRowMaxHeight: 40,
                          columnSpacing: 20,
                          showCheckboxColumn: false,
                          sortColumnIndex: 0,
                          sortAscending: ascending,
                          headingRowHeight: 32,
                          border: TableBorder.symmetric(
                              inside: const BorderSide(
                                  width: 1, color: mainColor700)),
                          headingRowColor: MaterialStateColor.resolveWith(
                              (states) => bgGrey),
                          columns: const <DataColumn>[
                            DataColumn(
                                label: Text("Ora",
                                    style: TextStyle(
                                        fontSize: 12, color: textColor))),
                            DataColumn(
                                label: Text("Classe",
                                    style: TextStyle(
                                        fontSize: 12, color: textColor))),
                            DataColumn(
                                label: Text("Docente assente",
                                    style: TextStyle(
                                        fontSize: 12, color: textColor))),
                            DataColumn(
                                label: Text("Sostituto 1",
                                    style: TextStyle(
                                        fontSize: 12, color: textColor))),
                            DataColumn(
                                label: Text("Sostituto 2",
                                    style: TextStyle(
                                        fontSize: 12, color: textColor))),
                            DataColumn(
                                tooltip: "Sostituzione a pagamento",
                                label: Text("Pag.",
                                    style: TextStyle(
                                        fontSize: 12, color: textColor))),
                            DataColumn(
                                label: SizedBox(
                                    width: 200,
                                    child: Text("Note",
                                        style: TextStyle(
                                            fontSize: 12, color: textColor)))),
                            DataColumn(
                                tooltip: "Firmata",
                                label: Text("Fir.",
                                    style: TextStyle(
                                        fontSize: 12, color: textColor))),
                          ],
                          rows: List<DataRow>.generate(snapshot.data!.length,
                              (int index) {
                            return DataRow(
                                color:
                                    MaterialStateProperty.resolveWith<Color?>(
                                        (Set<MaterialState> states) {
                                  if (states.contains(MaterialState.selected)) {
                                    return mainColor;
                                  }
                                  return null;
                                }),
                                cells: <DataCell>[
                                  DataCell(Text(
                                      snapshot.data![index].ora.toString(),
                                      style: const TextStyle(
                                          fontSize: 12,
                                          fontWeight: FontWeight.w700))),
                                  DataCell(Text(snapshot.data![index].classe,
                                      style: const TextStyle(
                                          fontSize: 12,
                                          fontWeight: FontWeight.w700))),
                                  DataCell(Text(
                                      snapshot.data![index].docAssente,
                                      style: const TextStyle(
                                          fontSize: 12,
                                          fontWeight: FontWeight.w700))),
                                  DataCell(Text(
                                      snapshot.data![index].docSostituto1,
                                      style: const TextStyle(
                                          fontSize: 12,
                                          fontWeight: FontWeight.w700))),
                                  DataCell(Text(
                                      snapshot.data![index].docSostituto2,
                                      style: const TextStyle(
                                          fontSize: 12,
                                          fontWeight: FontWeight.w700))),
                                  DataCell(Text(snapshot.data![index].pagamento,
                                      style: const TextStyle(
                                          fontSize: 12,
                                          fontWeight: FontWeight.w700))),
                                  DataCell(Text(snapshot.data![index].note,
                                      style: const TextStyle(
                                          fontSize: 12,
                                          fontWeight: FontWeight.w700))),
                                  DataCell(Text(snapshot.data![index].firmata,
                                      style: const TextStyle(
                                          fontSize: 12,
                                          fontWeight: FontWeight.w700))),
                                ],
                                selected: selected[index],
                                onSelectChanged: (bool? value) {
                                  setState(() {
                                    selected[index] = value!;
                                  });
                                });
                          })),
                    ),
                  ),
                ),
              ));
        } else if (snapshot.hasError) {
          return const Text("Qualcosa è andato storto :(");
        } else if (context.watch<General>().isEmpty &&
            !context.watch<General>().isLoading) {
          return Text(
            "Nessuna sostituzione per ${context.watch<General>().dataFormattata}",
            style: const TextStyle(color: textColor),
          );
        }
        return const Center(child: CircularProgressIndicator());
      },
    );
  }
}

浏览器错误信息

871main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'
66main.dart.js:26211 Another exception was thrown: Instance of 'minified:fy<void>'

排查方向及解决方案

1. 数组越界异常

代码中selected固定初始化100个元素,但接口返回的snapshot.data!.length可能超过100,构建版本中访问selected[index]会直接抛出异常,导致UI渲染异常显示灰色。
解决方式:
将selected改为动态匹配数据长度:

List<bool> selected = [];

// 在FutureBuilder的hasData分支内初始化
if (snapshot.hasData && !context.watch<General>().isLoading && !context.watch<General>().isEmpty) {
  if (selected.length != snapshot.data!.length) {
    selected = List<bool>.generate(snapshot.data!.length, (index) => false);
  }
  // 后续原有代码
}

2. FutureBuilder重复触发异常

context.watch<General>().dati在build方法中每次执行都会生成新的Future,导致FutureBuilder重复重建,引发状态紊乱。
解决方式:
在initState中一次性获取Future并复用:

late final Future<YourDataType> _datiFuture;

@override
void initState() {
  super.initState();
  _datiFuture = context.read<General>().dati;
}

@override
Widget build(BuildContext context) {
  return FutureBuilder(
    future: _datiFuture,
    builder: (context, snapshot) {
      // 原有builder代码
    },
  );
}

3. 压缩后的错误信息无法定位

浏览器中minified:fy<void>是混淆压缩后的异常提示,无法直接定位问题。
解决方式:
构建时关闭混淆,生成带调试信息的版本:

flutter build web --no-tree-shake-icons --dart-define=FLUTTER_WEB_DEBUG=true

部署该版本后,浏览器会输出清晰的错误栈,定位具体异常位置。

4. 自定义颜色常量被树摇优化删除

构建版本的树摇优化可能误删未被显式引用的颜色常量(如mainColor50、bgGrey),导致UI显示异常。
解决方式:
确保颜色常量在代码中被直接引用,或在主题配置中显式声明,避免被优化删除。


内容的提问来源于stack exchange,提问作者enrico cristaudo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 05:34:52