DataTable控件显示表格数据,DataTable需要设置行和列。
DataTable
DataTable({Key key,@required this.columns, //是DataTable的列@required this.rows, //是DataTable的每一行数据this.sortColumnIndex, //表示表格显示排序图标的索引this.sortAscending = true, //表示升序或者降序(默认是升序)this.onSelectAll,this.dataRowColor, //行背景色this.dataRowHeight, //行高度this.dataTextStyle, // 行文字样式this.headingRowColor, //表头背景色 headingRowColor: MaterialStateProperty.all(Colors.red),this.headingRowHeight, //表头行高度this.headingTextStyle, //表头文字样式this.horizontalMargin, //表格左右边距this.columnSpacing, //列间隔this.showCheckboxColumn = true,this.showBottomBorder = false, //是否展示底部边框this.dividerThickness, //分割线粗细})
简单示例

DataTable(// 表头columns: [DataColumn(label: Text('姓名')),DataColumn(label: Text('年龄')),],rows: [// 单行数据DataRow(cells: [DataCell(Text('张三')),DataCell(Text('20')),]),DataRow(cells: [DataCell(Text('李四')),DataCell(Text('24')),]),],),
DataColumn
const DataColumn({@required this.label, //标签,文本或者size=18的图标this.tooltip, //长按提示。 tooltip: '长按提示',this.numeric = false, //是否包含数字,该包含数字数据的列的单元格内容是否右对齐this.onSort, //排序时调用}) : assert(label != null);
显示排序图标

DataTable(sortColumnIndex: 1, //表示表格显示排序图标的索引sortAscending: true, //表示是否是升序columns: [DataColumn(label: Text('姓名')),DataColumn(label: Text('年龄'),onSort: (int columnIndex, bool ascending) {print('$columnIndex -- $ascending');// columnIndex 表示索引// ascending 表示变化之后的排序状态},),],...)
多列排序示例

import "package:flutter/material.dart";import 'package:app1/coms/base/empty_null/empty_null.dart';class TestPage extends StatefulWidget {@override_TestPageState createState() => _TestPageState();}class _TestPageState extends State<TestPage> {List<User> data = [User('张三', 18),User('李四', 244),User('王五', 2),User('马六', 3438),];int _sortColumnIndex = 0; //排序索引bool _sortAscending = true; //是否升序@overrideWidget build(BuildContext context) {return Scaffold(appBar: EmptyNull.appBar(),body: Container(child: DataTable(sortColumnIndex: _sortColumnIndex,sortAscending: _sortAscending,columns: [DataColumn(label: Text('姓名'),onSort: (int columnIndex, bool ascending) {setState(() {_sortColumnIndex = columnIndex;_sortAscending = ascending;if (ascending) {data.sort((a, b) => a.name.compareTo(b.name));} else {data.sort((a, b) => b.name.compareTo(a.name));}});},),DataColumn(label: Text('年龄'),onSort: (int columnIndex, bool ascending) {setState(() {_sortColumnIndex = columnIndex;_sortAscending = ascending;if (ascending) {data.sort((a, b) => a.age.compareTo(b.age));} else {data.sort((a, b) => b.age.compareTo(a.age));}});},),],rows: data.map((item) => DataRow(cells: [DataCell(Text('${item.name}')),DataCell(Text('${item.age}')),],)).toList(),),),);}}class User {User(this.name, this.age, {this.selected = false});String name;int age;bool selected;}
包含数字的列是否右对齐 numeric
默认情况下数据是左对齐的,让某一列右对齐只需设置DataColumn中numeric参数true。
columns: [DataColumn(label: Text('姓名')),DataColumn(label: Text('年龄'), numeric: true),],
DataRow
const DataRow({this.key,this.selected = false, //行是否被选中this.onSelectChanged, //点击行选中改变回调this.color,@required this.cells, //子项}) : assert(cells != null);
选中示例
设置DataRow中 selected 参数为true,可以显示其中一行被选中。onSelectChanged 参数是点击每一行数据时的回调。
我们并没有对全选、取消全选进行控制,但是演示发现:全选、取消全选时,真实数据也发生了变化,那么是怎么实现的? 答:全选、取消全选时,每一行的onSelectChanged都被回调了一次。
import "package:flutter/material.dart";import 'package:app1/coms/base/empty_null/empty_null.dart';class TestPage extends StatefulWidget {@override_TestPageState createState() => _TestPageState();}class _TestPageState extends State<TestPage> {List<User> data = [User('张三', 18),User('李四', 244),User('王五', 2),User('马六', 3438),];@overrideWidget build(BuildContext context) {return Scaffold(appBar: EmptyNull.appBar(),body: Container(child: DataTable(columns: [DataColumn(label: Text('姓名')),DataColumn(label: Text('年龄')),],rows: data.map((item) => DataRow(selected: item.selected,onSelectChanged: (selected) {print('${item.name} -- $selected');setState(() {item.selected = selected;});},cells: [DataCell(Text('${item.name}')),DataCell(Text('${item.age}')),],)).toList(),),),);}}class User {User(this.name, this.age, {this.selected = false});String name;int age;bool selected;}
DataCell
DataCell是DataRow中每一个子控件,DataCell子控件不一定是文本,也可以是图标等任意组件。
const DataCell(this.child, { //子部件,一般为Text或DropdownButtonthis.placeholder = false, //是否为占位符,若child为Text,显示占位符文本样式this.showEditIcon = false, //显示编辑图标,并非意义上的把child变为可编辑,需要结合onTapthis.onTap, //点击}) : assert(child != null);
给DataCell设置编辑图标:
DataCell(Text('name'),showEditIcon: true)
当然仅仅是一个图标,placeholder参数也是一样的,设置为true,仅仅是文字的样式变化了,onTap为点击回调,用法如下:
DataCell(Text('name'),placeholder: true,showEditIcon: true,onTap: (){print('DataCell onTap');},)
处理数据显示不全问题
当表格列比较多的时候,可以使用SingleChildScrollView包裹DataTable,显示不全时滚动显示。
