如何在Flutter/Dart中将DataTable的表头行固定?

移动开发 2026-07-09

好吧,我在学习Flutter,想要创建一个DataTable,其行是可滚动的(你可以把它们包在 SingleChildScrollView 里),但最上面的行始终可见。

我知道有些包可以实现这个功能,但我不想使用它们,因为这是出于学习目的。

我做了一个 Column 小部件,在其中放了一个 Table,它只有一行是表头,下面是一个 DataTable,但问题是 DataTable 需要columns参数。

以下是代码段:

return Column(
          children: [
            Table(
              children: [
                TableRow(
                  children: columns.map((col) {
                    return TableCell(child: col.label);
                  }).toList(),
                ),
              ],
            ),
            Expanded(
              child: SingleChildScrollView(
                scrollDirection: Axis.vertical,
                child: ConstrainedBox(
                  constraints: BoxConstraints(minWidth: constraints.maxWidth),
                  child: DataTable(
                    showCheckboxColumn: true,
                    headingRowColor: WidgetStateProperty.all(
                      const Color(0xFFF5F5F5),
                    ),
                    columnSpacing: 48,
                    horizontalMargin: 24,
                    sortColumnIndex: sortColumnIndex,
                    sortAscending: sortAscending,
                    columns: columns,
                    headingRowHeight: 0,
                    rows: rows,
                  ),
                ),
              ),
            )

得到的结果是:

enter image description here

现在的主要问题是,我可以把表格的某一行固定在 DataTable 的顶部并让它一直显示在顶部,但会出现两个表头列,一个来自 Table,另一个来自 DataTable,如图所示。

我要如何完全手动解决这个问题。

解决方案

你只需要把 Column(crossAxisAlignment: .stretch, 设置为默认值,而不是居中;

而在你有 horizontalMargin: 24, 时,需要在标签周围添加内边距。

    return Scaffold(
      backgroundColor: Colors.greenAccent,
      body: Column(
        crossAxisAlignment: .stretch,
        children: [
          Table(
            children: [
              TableRow(
                children: columns.map((col) {
                  return TableCell(
                    child: Padding(
                      padding: EdgeInsets.symmetric(horizontal: 24), //feel free to add vertical padding as well
                      child: col.label,
                    ),
                  );
                }).toList(),
              ),
            ],
          ),
          Expanded(
            child: SingleChildScrollView(
              scrollDirection: Axis.vertical,
              child: ConstrainedBox(
                constraints: BoxConstraints(minWidth: 120),
                child: DataTable(
                  showCheckboxColumn: true,
                  headingRowColor: WidgetStateProperty.all(
                    const Color(0xFFF5F5F5),
                  ),
                  columnSpacing: 48,
                  horizontalMargin: 24,
                  // sortColumnIndex: sortColumnIndex,
                  // sortAscending: sortAscending,
                  columns: columns,
                  headingRowHeight: 0,
                  rows: rows,
                ),
              ),
            ),
          ),
        ],
      ),
    );
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章