动态表格

一个完全可定制的数据表格,用于您的 Flutter 项目,您可以在其中编辑、删除、添加和更新表格中的值。

它构建于 PaginatedDataTable 之上

Dynamic_table_gif

入门

要使用 Dynamic_Table,只需添加 DynamicTable Widget

在此处查看示例 https://dynamic-table-example.web.app/

目录

功能

  • 添加新值
  • 更新值
  • 保存值
  • 删除值
  • 自定义样式
  • 不可编辑列

用法

不可编辑表格

DynamicTable(
  header: const Text("Person Table"),
  rowsPerPage: 5,
  showFirstLastButtons: true,
  availableRowsPerPage: const [
    5,
    10,
    15,
    20,
  ],// rowsPerPage should be in availableRowsPerPage
  columnSpacing: 60,
  showCheckboxColumn: true,
  onRowsPerPageChanged: (value) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text("Rows Per Page Changed to $value"),
      ),
    );
  },
  rows: [DynamicTableDataRow(
      index: index,
      onSelectChanged: (value) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: value ?? false
                ? Text("Row Selected index:$index")
                : Text("Row Unselected index:$index"),
          ),
        );
      },
      cells:[
        DynamicTableDataCell(value: "Name"),
        DynamicTableDataCell(value: "101"),
        DynamicTableDataCell(value: DateTime(2000, 2, 11)),
        DynamicTableDataCell(value: "Male"),
        DynamicTableDataCell(value:"Some other info about Aakash"),
      ],
    ),
  ],
  columns: [
    DynamicTableDataColumn(
        label: const Text("Name"),
        onSort: (columnIndex, ascending) {},
        dynamicTableInputType: DynamicTableTextInput()),
    // dynamicTableInputType: DynamicTableInputType.text()),
    DynamicTableDataColumn(
        label: const Text("Unique ID"),
        onSort: (columnIndex, ascending) {},
        isEditable: false,
        dynamicTableInputType: DynamicTableTextInput()),
    // dynamicTableInputType: DynamicTableInputType.text()),
    DynamicTableDataColumn(
      label: const Text("Birth Date"),
      onSort: (columnIndex, ascending) {},
      // dynamicTableInputType: DynamicTableDateInput()
      dynamicTableInputType: DynamicTableInputType.date(
        context: context,
        decoration: const InputDecoration(
            hintText: "Select Birth Date",
            suffixIcon: Icon(Icons.date_range),
            border: OutlineInputBorder()),
        initialDate: DateTime(1900),
        lastDate: DateTime.now().add(
          const Duration(days: 365),
        ),
      ),
    ),
    DynamicTableDataColumn(
      label: const Text("Gender"),
      // dynamicTableInputType: DynamicTableDropDownInput<String>()
      dynamicTableInputType: DynamicTableInputType.dropDown<String>(
        items: genderDropdown,
        selectedItemBuilder: (context) {
          return genderDropdown
              .map((e) => Text(e))
              .toList(growable: false);
        },
        decoration: const InputDecoration(
            hintText: "Select Gender", border: OutlineInputBorder()),
        displayBuilder: (value) =>
            value ??
            "", // How the string will be displayed in non editing mode
        itemBuilder: (value) {
          return DropdownMenuItem(
            value: value,
            child: Text(value),
          );
        },
      ),
    ),
    DynamicTableDataColumn(
        label: const Text("Other Info"),
        onSort: (columnIndex, ascending) {},
        dynamicTableInputType: DynamicTableInputType.text(
          decoration: const InputDecoration(
            hintText: "Enter Other Info",
            border: OutlineInputBorder(),
          ),
          maxLines: 100,
        )),
  ],
)

可编辑表格

要使表格可编辑,只需将 showActionsshowAddRowButtonshowDeleteAction 设置为 true,并添加 onRowEditonRowDeleteonRowSave 回调。

DynamicTable(
  onRowEdit: (index, row) {
    //TODO
  },
  onRowDelete: (index, row) {
    //TODO
  },
  onRowSave: (index, old, newValue) {
    //TODO
  },
  showActions: true,
  showAddRowButton: true,
  showDeleteAction: true,
);

可用回调

void Function(bool?)? onSelectAll

当用户使用标题行中的复选框选择或取消选择所有行时调用。

void Function(int)? onPageChanged

当用户切换到另一页时调用。

该值是当前显示页上第一行的索引。

void Function(int?)? onRowsPerPageChanged

当用户选择不同数量的每页行数时调用。

如果此值为 null,则将使用 [rowsPerPage] 提供的行数,并且不提供更改此值的控件。

bool Function(int, List<dynamic>)? onRowEdit

当用户点击行的编辑图标时调用。

返回 true 以允许编辑操作,返回 false 以阻止它。

如果允许操作,则该行将是可编辑的。

bool onRowEdit(int index, List<dynamic> row){
//Do some validation on row and return false if validation fails
if (index%2==1) {
  ScaffoldMessenger.of(context).showSnackBar(
   const SnackBar(
    content: Text("Cannot edit odd rows"),
  ),
);
return false; // The row will not open in editable mode
}
return true; // The row will open in editable mode
}

bool Function(int, List<dynamic>)? onRowDelete

当用户点击行的删除图标时调用。

返回 true 以允许删除操作,返回 false 以阻止它。

如果允许删除操作,则该行将从表中删除。

bool onRowDelete(int index, List<dynamic> row){
//Do some validation on row and return false if validation fails
if (row[0] == null) {
   ScaffoldMessenger.of(context).showSnackBar(
    const SnackBar(
     content: Text("Name cannot be null"),
    ),
  );
 return false;
}
return true;
}

List<dynamic>? Function(int, List<dynamic>, List<dynamic>)? onRowSave

当用户点击行的保存图标时调用。

返回 List<dynamic> newValue 以允许保存操作,返回 null 以阻止它。

newValue 必须是与列长度相同的列表。

如果允许保存操作,则该行将保存到表中。

oldValue 是编辑前的行值。newValue 是编辑后的行值。

List<dynamic>? onRowSave(int index, List<dynamic> oldValue, List<dynamic> newValue) {
//Do some validation on new value and return null if validation fails
if (newValue[0] == null) {
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(
        content: Text("Name cannot be null"),
         ),
    );
  return null;
}
// Do some modification to `newValue` and return `newValue`
newValue[0] = newValue[0].toString().toUpperCase(); // Convert name to uppercase
// Save new data to you list
myData[index] = newValue;
return newValue;
}

可用方法

首先创建一个 DynamicTableState 的 GlobalKey。将 key 传递给 DynamicTable 构造函数。

final tableKey = GlobalKey<DynamicTableState>();
DynamicTable(key:tableKey);

addRow()

tableKey.currentState?.addRow();

在表格的第 0 行添加一个新空行。showActions 参数必须为 true,因为该行将以编辑模式添加,并且要保存该行需要操作。

注意:无法向不可编辑列添加值。

addRowWithValues(List<dynamic> values, {bool isEditing = false})

tableKey.currentState?.addRowWithValues(`column1,column2...columnN`);

在表格的第 0 行添加一个带有值的带值新行。

如果传递了 isEditingtrue,则新添加的行将处于编辑模式。如果为 false,则该行将处于非编辑模式。

如果 isEditing 为 true,则 showActions 也必须为 true。

values 的长度必须等于 columns 的长度。

deleteRow(int index)

tableKey.currentState?.deleteRow(0);

删除给定 index 的行。

index 应为 index<rows.length && index>=0。

updateRow(int index, List<dynamic> values)

tableKey.currentState.?.updateRow(0, dummyData`column1,column2,...,columnN`);

使用给定的值更新 index 的列。

values 的长度必须等于 columns 的长度。

index 应为 index<rows.length && index>=0。

insertRow(int index, List<dynamic> values, {bool isEditing = false,})

tableKey.currentState?.insertRow(
30, dummyData`column1,column2,...,columnN`
isEditing: true);

在表格的 index 处插入一个带值的新行。

如果传递了 isEditingtrue,则新添加的行将处于编辑模式。如果为 false,则该行将处于非编辑模式。

如果 isEditing 为 true,则 showActions 也必须为 true

values 的长度必须等于 columns 的长度。

deleteAllRows()

tableKey.currentState?.deleteAllRows();

从表格中删除所有行。

deleteSelectedRows()

tableKey.currentState?.deleteSelectedRows();

仅从表格中删除选定的行。

getRowByIndex(int index)

tableKey.currentState?.getRowByIndex(10)

获取 index 索引处的行。

index 应为 index>=0 && index<rows.length

getSelectedRows()

tableKey.currentState?.getSelectedRows()

获取表格中所有选定的行。

getAllRows()

tableKey.currentState?.getAllRows()

获取表格中的所有行。

updateAllRows(List<List<dynamic>> data)

tableKey.currentState?.updateAllRows(data);

使用给定的 data 更新表格中的所有行。

data 的长度必须等于 rows.length

并且所有 data 的长度都必须等于 columns.length

selectRow(int index,bool isSelected)

根据给定的 isSelected 选择或取消选择索引为 ‘index’ 的行。

selectAllRows(bool isSeleted)

根据给定的 isSelected 选择或取消选择表格中的所有行。

问题

请在 问题跟踪器 中提交 issues、bug 或功能请求。

GitHub

查看 Github