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

Flutter中实现SfDataGrid表格行拖拽重排方案求助

SfDataGrid 行拖拽重排序实现方案

要给你的SfDataGrid实现行拖拽重排序,需要开启表格的拖拽支持,配合数据源的动态更新来完成,以下是修改后的完整代码及关键说明:

关键修改点

  • 在SfDataGrid中启用行拖拽,添加allowRowDrag: true并配置拖拽相关回调
  • 实现拖拽回调逻辑,处理行位置交换与数据源更新
  • 给EmployeeDataSource添加更新行顺序的方法,确保原始数据与表格数据同步

完整代码

import 'dart:core';
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';

class RegReqTable extends StatefulWidget {
  const RegReqTable({Key? key}) : super(key: key);
  @override
  State<RegReqTable> createState() => _RegReqTableState();
}

class _RegReqTableState extends State<RegReqTable> {
  List<Employee> employees = <Employee>[];
  late EmployeeDataSource employeeDataSource;
  int? draggedRowIndex;

  @override
  void initState() {
    super.initState();
    employees = getEmployeeData();
    employeeDataSource = EmployeeDataSource(employeeData: employees);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          const SizedBox(height: 20,),
          const Text('Requests',style: TextStyle(fontSize: 20,fontWeight: FontWeight.bold),),
          const SizedBox(height: 20,),
          Expanded(
            child: SfDataGrid(
              source: employeeDataSource,
              columnWidthMode: ColumnWidthMode.fill,
              allowRowDrag: true,
              rowDragGestureType: RowDragGestureType.longPress, // 长按触发拖拽,可改为tap点击触发
              onRowDragStart: (RowDragStartDetails details) {
                draggedRowIndex = details.rowIndex;
              },
              onRowDragUpdate: (RowDragUpdateDetails details) {
                final dropIndex = details.dropIndex;
                if (draggedRowIndex != null && dropIndex != null && draggedRowIndex != dropIndex) {
                  // 交换原始数据列表中的元素
                  setState(() {
                    final draggedEmployee = employees.removeAt(draggedRowIndex!);
                    employees.insert(dropIndex, draggedEmployee);
                    // 更新数据源
                    employeeDataSource.updateDataGridRows(employees);
                    draggedRowIndex = dropIndex;
                  });
                }
              },
              onRowDragEnd: (RowDragEndDetails details) {
                draggedRowIndex = null;
              },
              columns: <GridColumn>[
                GridColumn(
                    columnName: 'user',
                    label: Container(
                        padding: const EdgeInsets.all(16.0),
                        alignment: Alignment.center,
                        child: const Text('User'))),
                GridColumn(
                    columnName: 'request',
                    label: Container(
                        padding: const EdgeInsets.all(8.0),
                        alignment: Alignment.center,
                        child: const Text(
                          'Request details',
                          overflow: TextOverflow.ellipsis,
                        ))),
                GridColumn(
                    columnName: 'accept',
                    label: Container(
                        padding: const EdgeInsets.all(8.0),
                        alignment: Alignment.center,
                        child: const Text(
                          'Accept',
                          overflow: TextOverflow.ellipsis,
                        ))),
              ],
            ),
          ),
        ],
      ),
    );
  }

  List<Employee> getEmployeeData() {
    return [
      Employee('User 1','Blah blah blah'),
      Employee('User 2','Second request content'),
      Employee('User 3','Third request details'),
    ];
  }
}

class Employee {
  late String user;
  final String request;

  Employee(this.user, this.request);
}

class EmployeeDataSource extends DataGridSource {
  EmployeeDataSource({required List<Employee> employeeData}) {
    _employeeData = employeeData
        .map<DataGridRow>((e) =>
        DataGridRow(cells: [
          DataGridCell<String>(columnName: 'user', value: e.user),
          DataGridCell<String>(columnName: 'request', value: e.request),
          const DataGridCell<Widget>(columnName: 'accept', value: null),
        ]))
        .toList();
  }

  List<DataGridRow> _employeeData = [];

  @override
  List<DataGridRow> get rows => _employeeData;

  // 更新行数据的方法,同步视图与数据源
  void updateDataGridRows(List<Employee> employeeData) {
    _employeeData = employeeData
        .map<DataGridRow>((e) =>
        DataGridRow(cells: [
          DataGridCell<String>(columnName: 'user', value: e.user),
          DataGridCell<String>(columnName: 'request', value: e.request),
          const DataGridCell<Widget>(columnName: 'accept', value: null),
        ]))
        .toList();
    notifyListeners(); // 通知表格刷新
  }

  @override
  DataGridRowAdapter buildRow(DataGridRow row) {
    return DataGridRowAdapter(
        cells: row.getCells().map<Widget>((e) {
          return Container(
              alignment: Alignment.center,
              padding: const EdgeInsets.symmetric(horizontal: 8),
              child: e.columnName == 'accept'
                  ? LayoutBuilder(
                  builder: (BuildContext context, BoxConstraints constraints) {
                    return ElevatedButton(
                        style: ButtonStyle(
                          backgroundColor: MaterialStateProperty.all<Color>(Colors.green),
                        ),
                        onPressed: () {},
                        child: const Text('Accept'));
                  })
                  : Text(e.value.toString()));
        }).toList()
    );
  }
}

代码说明

  1. 拖拽配置:allowRowDrag: true开启行拖拽功能,rowDragGestureType设置触发拖拽的手势(支持长按/点击两种模式)
  2. 拖拽回调处理:
    • onRowDragStart记录被拖拽行的起始索引
    • onRowDragUpdate在拖拽过程中,交换原始数据列表中的元素,并调用数据源方法更新表格
    • onRowDragEnd清空拖拽索引,结束拖拽状态
  3. 数据源同步:新增updateDataGridRows方法,重新生成表格行数据并通知视图刷新,确保数据与视图始终一致

内容的提问来源于stack exchange,提问作者Aswin B

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 09:36:28