4 changed files with 181 additions and 224 deletions
@ -0,0 +1,158 @@ |
|||||||
|
import 'package:flutter/material.dart'; |
||||||
|
import 'package:syncfusion_flutter_datagrid/datagrid.dart'; |
||||||
|
|
||||||
|
abstract class SelectableItem { |
||||||
|
bool isSelected = false; |
||||||
|
} |
||||||
|
|
||||||
|
abstract class SelectableDataSource<T extends SelectableItem> extends DataGridSource { |
||||||
|
SelectableDataSource(this.items) { |
||||||
|
_selectionNotifier = ValueNotifier(false); |
||||||
|
} |
||||||
|
|
||||||
|
List<T> items; |
||||||
|
late final ValueNotifier<bool> _selectionNotifier; |
||||||
|
ValueNotifier<bool> get selectionNotifier => _selectionNotifier; |
||||||
|
|
||||||
|
void toggleAllSelection(bool value) { |
||||||
|
for (var item in items) { |
||||||
|
item.isSelected = value; |
||||||
|
} |
||||||
|
_updateSelectionState(); |
||||||
|
notifyListeners(); |
||||||
|
} |
||||||
|
|
||||||
|
void toggleRowSelection(int index, bool? value) { |
||||||
|
items[index].isSelected = value ?? false; |
||||||
|
_updateSelectionState(); |
||||||
|
notifyListeners(); |
||||||
|
} |
||||||
|
|
||||||
|
void _updateSelectionState() { |
||||||
|
final allSelected = items.isNotEmpty && items.every((item) => item.isSelected); |
||||||
|
final someSelected = items.isNotEmpty && items.any((item) => item.isSelected); |
||||||
|
_selectionNotifier.value = allSelected || someSelected; |
||||||
|
} |
||||||
|
|
||||||
|
void updateDataGridSource() { |
||||||
|
_updateSelectionState(); |
||||||
|
notifyListeners(); |
||||||
|
} |
||||||
|
|
||||||
|
void updateData(List<T> newItems) { |
||||||
|
items = newItems; |
||||||
|
notifyListeners(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class Field implements SelectableItem { |
||||||
|
Field(this.id, this.name, this.chineseName, this.type, this.remark, [this.isSelected = false]); |
||||||
|
|
||||||
|
final String id; |
||||||
|
final String name; |
||||||
|
final String chineseName; |
||||||
|
final String type; |
||||||
|
final String remark; |
||||||
|
@override |
||||||
|
bool isSelected; |
||||||
|
} |
||||||
|
|
||||||
|
// 索引数据模型 |
||||||
|
class Index implements SelectableItem { |
||||||
|
Index(this.indexName, this.isPrimary, this.indexFields, this.rule, [this.isSelected = false]); |
||||||
|
|
||||||
|
final String indexName; |
||||||
|
final String isPrimary; |
||||||
|
final String indexFields; |
||||||
|
final String rule; |
||||||
|
@override |
||||||
|
bool isSelected; |
||||||
|
} |
||||||
|
|
||||||
|
class FieldsDataSource extends SelectableDataSource<Field> { |
||||||
|
FieldsDataSource(List<Field> fields) : super(fields); |
||||||
|
|
||||||
|
@override |
||||||
|
List<DataGridRow> get rows => |
||||||
|
items |
||||||
|
.map( |
||||||
|
(field) => DataGridRow( |
||||||
|
cells: [ |
||||||
|
DataGridCell<bool>(columnName: 'select', value: field.isSelected), |
||||||
|
DataGridCell<String>(columnName: 'id', value: field.id), |
||||||
|
DataGridCell<String>(columnName: 'name', value: field.name), |
||||||
|
DataGridCell<String>(columnName: 'chineseName', value: field.chineseName), |
||||||
|
DataGridCell<String>(columnName: 'type', value: field.type), |
||||||
|
DataGridCell<String>(columnName: 'remark', value: field.remark), |
||||||
|
], |
||||||
|
), |
||||||
|
) |
||||||
|
.toList(); |
||||||
|
|
||||||
|
@override |
||||||
|
DataGridRowAdapter buildRow(DataGridRow row) { |
||||||
|
final rowIndex = effectiveRows.indexOf(row); |
||||||
|
return DataGridRowAdapter( |
||||||
|
cells: |
||||||
|
row.getCells().map<Widget>((cell) { |
||||||
|
if (cell.columnName == 'select') { |
||||||
|
return Center( |
||||||
|
child: Checkbox( |
||||||
|
value: items[rowIndex].isSelected, |
||||||
|
onChanged: (value) => toggleRowSelection(rowIndex, value), |
||||||
|
), |
||||||
|
); |
||||||
|
} |
||||||
|
return Container( |
||||||
|
alignment: Alignment.centerLeft, |
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8), |
||||||
|
child: Text(cell.value.toString(), overflow: TextOverflow.ellipsis), |
||||||
|
); |
||||||
|
}).toList(), |
||||||
|
); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 索引数据源 |
||||||
|
class IndexesDataSource extends SelectableDataSource<Index> { |
||||||
|
IndexesDataSource(List<Index> indexes) : super(indexes); |
||||||
|
|
||||||
|
@override |
||||||
|
List<DataGridRow> get rows => |
||||||
|
items |
||||||
|
.map( |
||||||
|
(index) => DataGridRow( |
||||||
|
cells: [ |
||||||
|
DataGridCell<bool>(columnName: 'select', value: index.isSelected), |
||||||
|
DataGridCell<String>(columnName: 'indexName', value: index.indexName), |
||||||
|
DataGridCell<String>(columnName: 'isPrimary', value: index.isPrimary), |
||||||
|
DataGridCell<String>(columnName: 'indexFields', value: index.indexFields), |
||||||
|
DataGridCell<String>(columnName: 'rule', value: index.rule), |
||||||
|
], |
||||||
|
), |
||||||
|
) |
||||||
|
.toList(); |
||||||
|
|
||||||
|
@override |
||||||
|
DataGridRowAdapter buildRow(DataGridRow row) { |
||||||
|
final rowIndex = effectiveRows.indexOf(row); |
||||||
|
return DataGridRowAdapter( |
||||||
|
cells: |
||||||
|
row.getCells().map<Widget>((cell) { |
||||||
|
if (cell.columnName == 'select') { |
||||||
|
return Center( |
||||||
|
child: Checkbox( |
||||||
|
value: items[rowIndex].isSelected, |
||||||
|
onChanged: (value) => toggleRowSelection(rowIndex, value), |
||||||
|
), |
||||||
|
); |
||||||
|
} |
||||||
|
return Container( |
||||||
|
alignment: Alignment.centerLeft, |
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8), |
||||||
|
child: Text(cell.value.toString(), overflow: TextOverflow.ellipsis), |
||||||
|
); |
||||||
|
}).toList(), |
||||||
|
); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue