Flutter DataTable新增行无法即时置顶问题求助
表格表单组件支持接收columns和rows数据,需求是当newRowPosition设为'top'时,点击「Add Row」按钮新增行需添加至表格顶部,但实际点击后新行仅显示在底部,只有重新打开表单才会出现在顶部。已尝试通过setState更新组件、为DataRow添加UniqueKey,问题仍未解决。
在addEmptyRow方法的newRowPosition == 'top'分支中,你正确地将空数据插入到了tableRecords的头部(tableRecords.insert(0, emptyData)),但更新rows列表时却用了rows.add(...)——这会把新行追加到列表末尾,而不是插入到头部。这就是为什么点击按钮时新行出现在底部,重新打开表单时因为会重新执行buildRows方法,从tableRecords从头构建行,所以新行才会显示在顶部。
将newRowPosition == 'top'分支中的rows.add(buildSingleRow(tableRecords.length - 1))改为rows.insert(0, buildSingleRow(0)),因为新插入的行在tableRecords的索引0位置,直接构建该行并插入到rows的头部即可。
修正后的addEmptyRow方法代码:
void addEmptyRow() { List<DataCell> cells = []; int indexOfRow = rows.length; Map<String, dynamic> emptyData = {}; List<dynamic> columns = tableFieldDetails .otherFieldProperties['table_configuration']['columns']; String columnName = ''; Map<String, dynamic> columnAccess = {}; for (int i = 0; i < columns.length; i++) { var column = columns[i]; columnName = column['name']; String dataType = column['type']; columnAccess = column['access']; if (!emptyData.containsKey(columnName)) { emptyData[columnName] = ''; } if (displayAggragtes) { cells.add(DataCell( buildDataCell(indexOfRow - 1, dataType, '', columnName, columnAccess, column, true), )); } } if (displayAggragtes) { tableRecords.insert(tableRecords.length - 1, emptyData); rows.insert(rows.length - 1, DataRow(cells: cells)); } else if (newRowPosition == '' || newRowPosition == 'bottom') { tableRecords.add(emptyData); rows.add(buildSingleRow((tableRecords.length - 1))); } else if (newRowPosition == 'top') { print('objectobjectobjectobjectobject poonammmmmmmmmmmmmmmmmm'); tableRecords.insert(0, emptyData); // 修复:将新行插入到rows头部 rows.insert(0, buildSingleRow(0)); } }
为了避免手动维护rows和tableRecords时出现数据不一致的问题,建议在build方法中直接根据tableRecords动态生成行列表,无需提前构建并手动维护:
@override Widget build(BuildContext context) { // 每次build时根据tableRecords重新生成行 final currentRows = tableRecords.asMap().entries.map((entry) { return buildSingleRow(entry.key); }).toList(); return SingleChildScrollView( scrollDirection: Axis.vertical, child: SingleChildScrollView( scrollDirection: Axis.horizontal, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ DataTable( columns: cols, rows: currentRows, border: TableBorder.all(color: Colors.grey), columnSpacing: 8, dataRowHeight: 60, headingRowColor: MaterialStateProperty.resolveWith( (states) => const Color(0xFFECF0FE)), ), Padding( padding: const EdgeInsets.only(top: 8.0), child: ElevatedButton( onPressed: () { setState(() { addEmptyRow(); }); }, child: const Text( 'Add Row', style: TextStyle(color: Colors.white), ), ), ), ], ), ), ); }
这样修改后,你只需要维护tableRecords的状态,rows会自动根据tableRecords生成,彻底避免手动操作行列表的错误。
内容的提问来源于stack exchange,提问作者poonamtomar34

