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

如何在Flutter DataTable的列标题中添加下拉菜单?

实现思路与代码示例

核心思路

  1. 维护切换状态:用StatefulWidget保存当前选中的单位("Bandejas"或"Plantas"),状态变化时自动触发UI重建。
  2. 自定义列标题:把"Cantidad"列的标题改成包含文本和下拉按钮的组合组件,替换默认的纯文本标题。
  3. 动态渲染单元格:根据选中的单位,在DataTable的单元格里显示对应字段的值。

具体实现步骤

1. 定义数据模型

假设你的API返回的数据包含两个单位对应的数值字段,先定义一个数据类来存储单条数据:

class InventoryItem {
  final String name;
  final int crates; // 对应Bandejas
  final int plants; // 对应Plantas
  // 其他业务字段...

  InventoryItem({required this.name, required this.crates, required this.plants});
}

2. 维护切换状态

在页面的State类里添加状态变量,用来记录当前选中的单位:

class _InventoryPageState extends State<InventoryPage> {
  String _selectedUnit = "Bandejas"; // 默认选中第一个选项
  List<InventoryItem> _inventoryList = [];

  @override
  void initState() {
    super.initState();
    _fetchDataFromApi(); // 调用你的API请求方法获取数据
  }

  // ... 其他业务方法(比如API请求)
}

3. 自定义带下拉按钮的列标题

在DataTable的columns列表中,修改"Cantidad"列的label为包含下拉按钮的Row组件:

DataColumn(
  label: Row(
    mainAxisSize: MainAxisSize.min,
    children: [
      const Text("Cantidad"),
      const SizedBox(width: 8), // 文本和下拉按钮之间的间距
      DropdownButton<String>(
        value: _selectedUnit,
        items: const [
          DropdownMenuItem(value: "Bandejas", child: Text("Bandejas")),
          DropdownMenuItem(value: "Plantas", child: Text("Plantas")),
        ],
        onChanged: (newValue) {
          if (newValue != null) {
            setState(() {
              _selectedUnit = newValue;
            });
          }
        },
        underline: const SizedBox(), // 去掉默认下划线,让样式更贴合标题
        iconSize: 16, // 缩小下拉箭头的尺寸,更协调
      ),
    ],
  ),
)

4. 根据选中单位动态渲染单元格

在DataRow的cells列表里,根据_selectedUnit的值切换显示对应字段:

DataRow(cells: [
  DataCell(Text(item.name)),
  // 其他列的单元格...
  DataCell(
    Text(
      _selectedUnit == "Bandejas" ? "${item.crates}" : "${item.plants}",
    ),
  ),
])

完整示例片段

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

  @override
  State<InventoryPage> createState() => _InventoryPageState();
}

class _InventoryPageState extends State<InventoryPage> {
  String _selectedUnit = "Bandejas";
  List<InventoryItem> _inventoryList = [];

  @override
  void initState() {
    super.initState();
    // 模拟API返回的数据
    _inventoryList = [
      InventoryItem(name: "Producto A", crates: 12, plants: 24),
      InventoryItem(name: "Producto B", crates: 8, plants: 16),
      InventoryItem(name: "Producto C", crates: 20, plants: 40),
    ];
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Inventario")),
      body: SingleChildScrollView(
        child: DataTable(
          columns: [
            const DataColumn(label: Text("Nombre")),
            // 自定义Cantidad列标题
            DataColumn(
              label: Row(
                mainAxisSize: MainAxisSize.min,
                children: [
                  const Text("Cantidad"),
                  const SizedBox(width: 8),
                  DropdownButton<String>(
                    value: _selectedUnit,
                    items: const [
                      DropdownMenuItem(value: "Bandejas", child: Text("Bandejas")),
                      DropdownMenuItem(value: "Plantas", child: Text("Plantas")),
                    ],
                    onChanged: (newValue) {
                      if (newValue != null) {
                        setState(() {
                          _selectedUnit = newValue;
                        });
                      }
                    },
                    underline: const SizedBox(),
                    iconSize: 16,
                  ),
                ],
              ),
            ),
          ],
          rows: _inventoryList.map((item) {
            return DataRow(cells: [
              DataCell(Text(item.name)),
              DataCell(
                Text(
                  _selectedUnit == "Bandejas" ? "${item.crates}" : "${item.plants}",
                ),
              ),
            ]);
          }).toList(),
        ),
      ),
    );
  }
}

class InventoryItem {
  final String name;
  final int crates;
  final int plants;

  InventoryItem({required this.name, required this.crates, required this.plants});
}

额外提示

  • 如果API返回的不是直接的两个数值字段,而是需要通过计算转换(比如1箱=2株),可以在setState更新_selectedUnit时提前处理好数据,或者在DataCell里直接计算显示。
  • 可以根据UI需求调整下拉按钮的样式,比如修改字号、颜色,让它和标题文本更匹配。

内容的提问来源于stack exchange,提问作者Sistemas Kolbasiuk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 07:01:20