Flutter Table组件如何拆分底部行?需分为超时时间与停止时间
Flutter Table组件实现底部行拆分为上下两行需求
我用Flutter的Table组件创建了一个多列表格,现在需要把表格底部的行拆分为上下两行:上方行对应“超时时间(timeout time)”,下方行对应“停止时间(stop time)”,尝试查找资料后未找到实现方法,寻求解决方案。
现有代码
Container( margin: EdgeInsets.only(top: 10,right: 310), child: Table( columnWidths: { 0: FlexColumnWidth(24), 1: FlexColumnWidth(12), 2: FlexColumnWidth(12), }, border: TableBorder.all( color: Colors.black, style: BorderStyle.solid, width: 2), children: [ TableRow( children: [ Container( padding: EdgeInsets.only(top: 14,left: 4), height: 50, color: Colors.cyan, child: Column(children: [ Text( 'Layer No', style: TextStyle(fontSize: 20), ) ]), ), Container( height: 50, color: Colors.white, child: Container( padding: EdgeInsets.only(top: 15), color: Colors.white, child: Column(children: [ Text( '1', style: TextStyle(fontSize: 20), ) ]), ), ), Container( height: 50, color: Colors.white, child: Container( padding: EdgeInsets.only(top: 15), color: Colors.white, child: Column(children: [ Text( '2', style: TextStyle(fontSize: 20), ) ]), ), ), Container( height: 50, color: Colors.white, child: Container( padding: EdgeInsets.only(top: 15), color: Colors.white, child: Column(children: [ Text( '3', style: TextStyle(fontSize: 20), ) ]), ), ), ], ), TableRow( children: [ Container( padding: EdgeInsets.only(top: 15), height: 50, color: Colors.cyan, child: Column(children: [ Text( 'Capacity', style: TextStyle(fontSize: 20), ) ]), ), TableCell( verticalAlignment: TableCellVerticalAlignment.fill, child: Container( padding: EdgeInsets.only(top: 1,left: 4 ), color: Colors.white, child: Column(children: [ TextField( inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d{0,2}$'))], controller: wholelayerController1, focusNode: _wholelayerfocusNode1, decoration: InputDecoration(border: InputBorder.none), style: TextStyle(fontSize: 18,), ), ]), ), ), Container( padding: EdgeInsets.only(top: 1,left: 6 ), color: Colors.white, child: Column(children: [ TextField( inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d{0,2}$'))], controller: wholelayerController2, focusNode: _wholelayerfocusNode2, decoration: InputDecoration(border: InputBorder.none), style: TextStyle(fontSize: 18,), ), ]), ), Container( padding: EdgeInsets.only(top: 1,left: 4 ), color: Colors.white, child: Column(children: [ TextField( inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d{0,2}$'))], controller: wholelayerController3, focusNode: _wholelayerfocusNode3, decoration: InputDecoration(border: InputBorder.none), style: TextStyle(fontSize: 18,), ), ]), ), ], ), ], ), ),
现有效果

期望效果

解决方案
Flutter的Table组件本身不直接支持单元格跨行,但可以通过添加两个独立的TableRow来实现需求:第一行对应“超时时间”,第二行对应“停止时间”,每行的第一列设置为青色背景,右侧列放置对应的输入框。
修改后的代码示例:
Container( margin: EdgeInsets.only(top: 10, right: 310), child: Table( columnWidths: { 0: FlexColumnWidth(24), 1: FlexColumnWidth(12), 2: FlexColumnWidth(12), }, border: TableBorder.all(color: Colors.black, style: BorderStyle.solid, width: 2), children: [ // Layer No 行 TableRow( children: [ Container( padding: EdgeInsets.only(top: 14, left: 4), height: 50, color: Colors.cyan, child: Text('Layer No', style: TextStyle(fontSize: 20)), ), Container( height: 50, color: Colors.white, child: Center(child: Text('1', style: TextStyle(fontSize: 20))), ), Container( height: 50, color: Colors.white, child: Center(child: Text('2', style: TextStyle(fontSize: 20))), ), Container( height: 50, color: Colors.white, child: Center(child: Text('3', style: TextStyle(fontSize: 20))), ), ], ), // Capacity 行 TableRow( children: [ Container( padding: EdgeInsets.only(top: 15), height: 50, color: Colors.cyan, child: Text('Capacity', style: TextStyle(fontSize: 20)), ), Container( padding: EdgeInsets.only(top: 1, left: 4), color: Colors.white, child: TextField( inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d{0,2}$'))], controller: wholelayerController1, focusNode: _wholelayerfocusNode1, decoration: InputDecoration(border: InputBorder.none), style: TextStyle(fontSize: 18), ), ), Container( padding: EdgeInsets.only(top: 1, left: 6), color: Colors.white, child: TextField( inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d{0,2}$'))], controller: wholelayerController2, focusNode: _wholelayerfocusNode2, decoration: InputDecoration(border: InputBorder.none), style: TextStyle(fontSize: 18), ), ), Container( padding: EdgeInsets.only(top: 1, left: 4), color: Colors.white, child: TextField( inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d{0,2}$'))], controller: wholelayerController3, focusNode: _wholelayerfocusNode3, decoration: InputDecoration(border: InputBorder.none), style: TextStyle(fontSize: 18), ), ), ], ), // 超时时间 行 TableRow( children: [ Container( padding: EdgeInsets.only(top: 15), height: 50, color: Colors.cyan, child: Text('超时时间', style: TextStyle(fontSize: 20)), ), Container( padding: EdgeInsets.only(top: 1, left: 4), color: Colors.white, child: TextField( inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d{0,2}$'))], // 新增超时时间对应的controller和focusNode controller: timeoutController1, focusNode: _timeoutfocusNode1, decoration: InputDecoration(border: InputBorder.none), style: TextStyle(fontSize: 18), ), ), Container( padding: EdgeInsets.only(top: 1, left: 6), color: Colors.white, child: TextField( inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d{0,2}$'))], controller: timeoutController2, focusNode: _timeoutfocusNode2, decoration: InputDecoration(border: InputBorder.none), style: TextStyle(fontSize: 18), ), ), Container( padding: EdgeInsets.only(top: 1, left: 4), color: Colors.white, child: TextField( inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d{0,2}$'))], controller: timeoutController3, focusNode: _timeoutfocusNode3, decoration: InputDecoration(border: InputBorder.none), style: TextStyle(fontSize: 18), ), ), ], ), // 停止时间 行 TableRow( children: [ Container( padding: EdgeInsets.only(top: 15), height: 50, color: Colors.cyan, child: Text('停止时间', style: TextStyle(fontSize: 20)), ), Container( padding: EdgeInsets.only(top: 1, left: 4), color: Colors.white, child: TextField( inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d{0,2}$'))], // 新增停止时间对应的controller和focusNode controller: stopController1, focusNode: _stopfocusNode1, decoration: InputDecoration(border: InputBorder.none), style: TextStyle(fontSize: 18), ), ), Container( padding: EdgeInsets.only(top: 1, left: 6), color: Colors.white, child: TextField( inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d{0,2}$'))], controller: stopController2, focusNode: _stopfocusNode2, decoration: InputDecoration(border: InputBorder.none), style: TextStyle(fontSize: 18), ), ), Container( padding: EdgeInsets.only(top: 1, left: 4), color: Colors.white, child: TextField( inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d{0,2}$'))], controller: stopController3, focusNode: _stopfocusNode3, decoration: InputDecoration(border: InputBorder.none), style: TextStyle(fontSize: 18), ), ), ], ), ], ), )
说明
- 在原Table的children列表中新增两个TableRow,分别对应“超时时间”和“停止时间”行;
- 为每行的第一列设置青色背景,与之前的表头风格保持一致;
- 右侧三列分别添加对应的输入框,需要提前定义好超时时间和停止时间对应的
TextEditingController和FocusNode; - 代码中简化了原有的嵌套Container结构,直接使用
Center或直接放置文本/输入框,保持布局简洁。
内容的提问来源于stack exchange,提问作者newcomer
相关产品推荐
相关产品推荐

