Syncfusion Flutter DataGrid:如何启用拖放列重新排序和列大小调整

问题描述 投票:0回答:1

Syncfusion Flutter DataGrid:如何启用拖放列重新排序和列大小调整

我无法使用拖放列和调整列大小功能创建 Syncfusion 的 Flutter DataGrid 小部件。我尝试这样做,但它没有给我预期的输出,因为调整列的大小不起作用。


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

void main() {
  runApp(const MyApp());
}

/// The application that contains datagrid on it.
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(),
    );
  }
}

/// The home page of the application which hosts the datagrid. 

class MyHomePage extends StatefulWidget {
  /// Creates the home page.

  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': double.nan,
    'name': double.nan,
    'designation': double.nan,
    'email': double.nan,
    'salary': double.nan,
  };

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Syncfusion Flutter DataGrid')),
      body: SfDataGrid(
        source: employeeDataSource,
        columnWidthMode: ColumnWidthMode.fill,

        allowColumnsDragging: true,
        columns: columns,
        columnResizeMode: ColumnResizeMode.onResizeEnd,
        allowColumnsResizing: true,
        //  defaultColumnWidth: colwidth,
        onColumnResizeUpdate: (ColumnResizeUpdateDetails details) {
          setState(() {
            columnWidths[details.column.columnName] = 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());
  }

  refreshDataGrid() {
    notifyListeners();
  }
}

/// Custom business object class which contains properties to hold the detailed
/// information about the employee which will be rendered in datagrid.
class Employee {
  /// Creates the employee class with required details.
  Employee(this.id, this.name, this.designation, this.email, this.salary);

  /// Id of an employee.
  final int id;

  /// Name of an employee.
  final String name;

  /// Designation of an employee.
  final String designation;

  final String email;

  /// Salary of an employee.
  final int salary;

  /// Overrides the indexing operator to provide access to specific properties of the  [Employee] class.
  operator [](Object? value) {
    if (value == 'id') {
      return id;
    } else if (value == 'name') {
      return name;
    } else if (value == 'designation') {
      return designation;
    } else if (value == 'email') {
      return email;
    } else if (value == 'salary') {
      return salary;
    } else {
      throw ArgumentError('Invalid property: $value');
    }
  }
}

List<Employee> getEmployeeData() {
  return [
    Employee(10001, 'Jack Anderson', 'Manager', '[email protected]', 120000),
    Employee(10002, 'Olivia Wilson', 'Developer', '[email protected]', 500000),
    Employee(10003, 'Emma Wilson', 'Developer', '[email protected]', 49000),
    Employee(10004, 'Thomas Hardy', 'Developer', '[email protected]', 48000),
    Employee(10005, 'Mia Garcia', 'Developer', '[email protected]', 47000),
    Employee(10006, 'John Smith', 'Developer', '[email protected]', 43000),
    Employee(10007, 'Maria Andres', 'Developer', '[email protected]', 41000),
    Employee(10008, 'Samuel Martinez', 'Developer', '[email protected]', 40000),
    Employee(10009, 'Hanna Moos', 'Developer', '[email protected]', 40000),
    Employee(10010, 'Amelia Young', 'Developer', '[email protected]', 39000),
    Employee(
        10011, 'Patricio Simpson', 'Developer', '[email protected]', 39000)
  ];
}

flutter datagrid drag-and-drop resize syncfusion
1个回答
0
投票

在对象实例中管理列以实现拖放功能的情况下,必须更新实例中相应的列宽度。


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

void main() {
  runApp(const MyApp());
}

/// The application that contains datagrid on it.
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(),
    );
  }
}

/// The home page of the application which hosts the datagrid.

class MyHomePage extends StatefulWidget {
  /// Creates the home page.

  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',
          label: Container(
              padding: const EdgeInsets.all(16.0),
              alignment: Alignment.center,
              child: const Text(
                'ID',
              ))),
      GridColumn(
          columnName: 'name',
          label: Container(
              padding: const EdgeInsets.all(8.0),
              alignment: Alignment.center,
              child: const Text('Name'))),
      GridColumn(
          columnName: 'designation',
          label: Container(
              padding: const EdgeInsets.all(8.0),
              alignment: Alignment.center,
              child: const Text(
                'Designation',
                overflow: TextOverflow.ellipsis,
              ))),
      GridColumn(
          columnName: 'email',
          label: Container(
              padding: const EdgeInsets.all(8.0),
              alignment: Alignment.center,
              child: const Text(
                'Email',
                overflow: TextOverflow.ellipsis,
              ))),
      GridColumn(
          columnName: 'salary',
          label: Container(
              padding: const EdgeInsets.all(8.0),
              alignment: Alignment.center,
              child: const Text('Salary'))),
    ];
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Syncfusion Flutter DataGrid')),
      body: SfDataGrid(
        source: employeeDataSource,
        columnWidthMode: ColumnWidthMode.fill,

        allowColumnsDragging: true,
        columns: columns,
        columnResizeMode: ColumnResizeMode.onResizeEnd,
        allowColumnsResizing: true,
        //  defaultColumnWidth: colwidth,
        onColumnResizeUpdate: (ColumnResizeUpdateDetails details) {
          setState(() {
            int index = columns.indexOf(columns.firstWhere(
                (element) => element.columnName == details.column.columnName));

            columns[index] = GridColumn(
                columnName: details.column.columnName,
                width: details.width,
                label: details.column.label);
          });

          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());
  }

  refreshDataGrid() {
    notifyListeners();
  }
}

/// Custom business object class which contains properties to hold the detailed
/// information about the employee which will be rendered in datagrid.
class Employee {
  /// Creates the employee class with required details.
  Employee(this.id, this.name, this.designation, this.email, this.salary);

  /// Id of an employee.
  final int id;

  /// Name of an employee.
  final String name;

  /// Designation of an employee.
  final String designation;

  final String email;

  /// Salary of an employee.
  final int salary;

  /// Overrides the indexing operator to provide access to specific properties of the  [Employee] class.
  operator [](Object? value) {
    if (value == 'id') {
      return id;
    } else if (value == 'name') {
      return name;
    } else if (value == 'designation') {
      return designation;
    } else if (value == 'email') {
      return email;
    } else if (value == 'salary') {
      return salary;
    } else {
      throw ArgumentError('Invalid property: $value');
    }
  }
}

List<Employee> getEmployeeData() {
  return [
    Employee(10001, 'Jack Anderson', 'Manager', '[email protected]', 120000),
    Employee(10002, 'Olivia Wilson', 'Developer', '[email protected]', 500000),
    Employee(10003, 'Emma Wilson', 'Developer', '[email protected]', 49000),
    Employee(10004, 'Thomas Hardy', 'Developer', '[email protected]', 48000),
    Employee(10005, 'Mia Garcia', 'Developer', '[email protected]', 47000),
    Employee(10006, 'John Smith', 'Developer', '[email protected]', 43000),
    Employee(10007, 'Maria Andres', 'Developer', '[email protected]', 41000),
    Employee(10008, 'Samuel Martinez', 'Developer', '[email protected]', 40000),
    Employee(10009, 'Hanna Moos', 'Developer', '[email protected]', 40000),
    Employee(10010, 'Amelia Young', 'Developer', '[email protected]', 39000),
    Employee(
        10011, 'Patricio Simpson', 'Developer', '[email protected]', 39000)
  ];
}

© www.soinside.com 2019 - 2024. All rights reserved.