Syncfusion Flutter DataGrid:列拖拽重排与调整大小功能异常排查
问题分析与修复方案
你的Syncfusion Flutter DataGrid列调整大小功能失效,核心问题有三个:
ColumnWidthMode.fill覆盖手动宽度控制
开启该模式后,列宽会自动填充整个DataGrid宽度,手动设置的width属性和调整操作会被框架忽略,这是功能失效的主要原因。初始列宽使用
double.nandouble.nan表示自动计算宽度,在fill模式下会完全由框架接管,无法触发手动调整逻辑。列宽更新未同步到
columns列表onColumnResizeUpdate中仅更新了columnWidths,但没有修改columns列表中对应列的width属性,导致UI无法感知宽度变化。
修复步骤
1. 移除columnWidthMode: ColumnWidthMode.fill
若需手动调整列宽,不要使用填充模式,改用固定初始宽度或自适应内容宽度。
2. 初始化有效列宽
将columnWidths的初始值从double.nan改为具体数值,示例:
late Map<String, double> columnWidths = { 'id': 80, 'name': 150, 'designation': 180, 'email': 220, 'salary': 100, };
3. 同步更新列宽到columns列表
在onColumnResizeUpdate中,更新columnWidths的同时,找到对应列并修改其width属性,触发UI刷新:
onColumnResizeUpdate: (ColumnResizeUpdateDetails details) { setState(() { columnWidths[details.column.columnName] = details.width; final index = columns.indexWhere((col) => col.columnName == details.column.columnName); if (index != -1) { columns[index] = columns[index].copyWith(width: details.width); } }); return true; },
修改后的完整代码
import 'package:flutter/material.dart'; import 'package:syncfusion_flutter_datagrid/datagrid.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: 'Syncfusion DataGrid Demo', debugShowCheckedModeBanner: false, theme: ThemeData(primarySwatch: Colors.blue), home: const MyHomePage(), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({Key? key}) : super(key: key); @override MyHomePageState createState() => MyHomePageState(); } class MyHomePageState extends State<MyHomePage> { List<Employee> employees = <Employee>[]; late List<GridColumn> columns; late EmployeeDataSource employeeDataSource; @override void initState() { super.initState(); columns = getColumns; employees = getEmployeeData(); employeeDataSource = EmployeeDataSource(employees: employees, columns: columns); } List<GridColumn> get getColumns { return <GridColumn>[ GridColumn( columnName: 'id', width: columnWidths['id']!, label: Container( padding: const EdgeInsets.all(16.0), alignment: Alignment.center, child: const Text('ID'))), GridColumn( columnName: 'name', width: columnWidths['name']!, label: Container( padding: const EdgeInsets.all(8.0), alignment: Alignment.center, child: const Text('Name'))), GridColumn( columnName: 'designation', width: columnWidths['designation']!, label: Container( padding: const EdgeInsets.all(8.0), alignment: Alignment.center, child: const Text('Designation', overflow: TextOverflow.ellipsis))), GridColumn( columnName: 'email', width: columnWidths['email']!, label: Container( padding: const EdgeInsets.all(8.0), alignment: Alignment.center, child: const Text('Email', overflow: TextOverflow.ellipsis))), GridColumn( columnName: 'salary', width: columnWidths['salary']!, label: Container( padding: const EdgeInsets.all(8.0), alignment: Alignment.center, child: const Text('Salary'))), ]; } late Map<String, double> columnWidths = { 'id': 80, 'name': 150, 'designation': 180, 'email': 220, 'salary': 100, }; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Syncfusion Flutter DataGrid')), body: SfDataGrid( source: employeeDataSource, allowColumnsDragging: true, columns: columns, columnResizeMode: ColumnResizeMode.onResizeEnd, allowColumnsResizing: true, onColumnResizeUpdate: (ColumnResizeUpdateDetails details) { setState(() { columnWidths[details.column.columnName] = details.width; final index = columns.indexWhere((col) => col.columnName == details.column.columnName); if (index != -1) { columns[index] = columns[index].copyWith(width: details.width); } }); return true; }, onColumnDragging: (DataGridColumnDragDetails details) { if (details.action == DataGridColumnDragAction.dropped && details.to != null) { final GridColumn rearrangeColumn = columns[details.from]; columns.removeAt(details.from); columns.insert(details.to!, rearrangeColumn); employeeDataSource.buildDataGridRows(); employeeDataSource.refreshDataGrid(); } return true; }, ), ); } } class EmployeeDataSource extends DataGridSource { EmployeeDataSource({required this.employees, required this.columns}) { buildDataGridRows(); } void buildDataGridRows() { dataGridRows = employees.map<DataGridRow>((employee) { return DataGridRow( cells: columns.map<DataGridCell>((column) { return DataGridCell( columnName: column.columnName, value: employee[column.columnName], ); }).toList()); }).toList(); } List<Employee> employees = []; List<GridColumn> columns = []; List<DataGridRow> dataGridRows = []; @override List<DataGridRow> get rows => dataGridRows; @override DataGridRowAdapter? buildRow(DataGridRow row) { return DataGridRowAdapter( cells: row.getCells().map((dataGridCell) { return Container( alignment: Alignment.center, padding: const EdgeInsets.symmetric(horizontal: 8.0), child: Text(dataGridCell.value.toString())); }).toList()); } void refreshDataGrid() { notifyListeners(); } } class Employee { Employee(this.id, this.name, this.designation, this.email, this.salary); final int id; final String name; final String designation; final String email; final int salary; operator [](Object? value) { if (value == 'id') return id; if (value == 'name') return name; if (value == 'designation') return designation; if (value == 'email') return email; if (value == 'salary') return salary; throw ArgumentError('Invalid property: $value'); } } List<Employee> getEmployeeData() { return [ Employee(10001, 'Jack Anderson', 'Manager', 'jack@gmail.com', 120000), Employee(10002, 'Olivia Wilson', 'Developer', 'olivia@gmail.com', 500000), Employee(10003, 'Emma Wilson', 'Developer', 'emma.wilson@gmail.com', 49000), Employee(10004, 'Thomas Hardy', 'Developer', 'thomas@gmail.com', 48000), Employee(10005, 'Mia Garcia', 'Developer', 'mia.garcia@gmail.com', 47000), Employee(10006, 'John Smith', 'Developer', 'john@gmail.com', 43000), Employee(10007, 'Maria Andres', 'Developer', 'maria@gmail.com', 41000), Employee(10008, 'Samuel Martinez', 'Developer', 'samuel@gmail.com', 40000), Employee(10009, 'Hanna Moos', 'Developer', 'hanna@gmail.com', 40000), Employee(10010, 'Amelia Young', 'Developer', 'amelia@gmail.com', 39000), Employee(10011, 'Patricio Simpson', 'Developer', 'patricio@gmail.com', 39000) ]; }
内容的提问来源于stack exchange,提问作者nothing
相关产品推荐
相关产品推荐

