Flutter(30):Material组件之DataTable

Flutter教学目录持续更新中

Github源代码持续更新中

1.DataTable介绍

数据表显示表格数据,需要设置行和列

2.DataTable属性

  • columns:DataColumn 行
  • sortColumnIndex:索引在行的位置
  • sortAscending = true:升序/降序 只有UI变化,排序需要自己实现
  • onSelectAll:全选回调,默认实现全选操作
  • dataRowHeight = kMinInteractiveDimension:数据内容每列高度
  • headingRowHeight = 56.0:头部每列高度
  • horizontalMargin = 24.0:表格左右外边距
  • columnSpacing = 56.0:行每个子节点宽度
  • showCheckboxColumn = true:是否显示Checkbox
  • dividerThickness = 1.0:间隔线高度
  • rows:DataRow 列

3.DataColumn属性

  • label:子widget
  • tooltip:长按提示
  • numeric = false:是否右对齐
  • onSort:升序/降序

4.DataRow属性

  • selected = false:是否选中
  • onSelectChanged:选中回调
  • color:背景色
  • cells:子widgets

5.DataCell属性

  • child:子widget
  • placeholder = false:是都占位
  • showEditIcon = false:是否展示编辑
  • onTap:点击事件

6.DataTable基本用法

  • 一个基础的DataTable需要设置columns列,rows行
  • 由于DataTable本身是不具备滑动属性,所以当数据比较多的时候需要嵌套滑动组件,这里我们使用两个SingleChildScrollView来完成纵向横向的滑动


    1601631902(1).png
class TypeBean {
  const TypeBean({this.name});

  final String name;
}

class StudentGradesBean {
  String name;
  int studentId;
  int language;
  int math;
  int english;
  int physical;
  int chemistry;
  int biological;
  int geography;
  int political;
  int history;
  bool isSelected;

  StudentGradesBean(
    this.name,
    this.studentId,
    this.language,
    this.math,
    this.english,
    this.physical,
    this.chemistry,
    this.biological,
    this.geography,
    this.political,
    this.history, {
    this.isSelected = false,
  });
}

var _typeList = [
    TypeBean(name: '姓名'),
    TypeBean(name: '学号'),
    TypeBean(name: '语文'),
    TypeBean(name: '数学'),
    TypeBean(name: '英语'),
    TypeBean(name: '物理'),
    TypeBean(name: '化学'),
    TypeBean(name: '生物'),
    TypeBean(name: '地理'),
    TypeBean(name: '政治'),
    TypeBean(name: '历史'),
  ];

  List<DataColumn> _dataColumnList = [];

  var _studentGradesList = [
    StudentGradesBean('张三', 1, 89, 88, 100, 76, 81, 77, 95, 85, 80),
    StudentGradesBean('李四', 2, 95, 100, 90, 72, 65, 88, 66, 79, 96),
    StudentGradesBean('王二', 3, 100, 67, 87, 96, 89, 69, 79, 78, 73),
    StudentGradesBean('麻子', 4, 85, 75, 86, 91, 100, 66, 100, 90, 83),
    StudentGradesBean('王五', 5, 89, 88, 100, 76, 81, 77, 95, 85, 80),
    StudentGradesBean('赵四', 6, 95, 100, 90, 72, 65, 88, 66, 79, 96),
    StudentGradesBean('陈二', 7, 100, 67, 87, 96, 89, 69, 79, 78, 73),
    StudentGradesBean('李世民', 8, 85, 75, 86, 91, 100, 66, 100, 90, 83),
    StudentGradesBean('王老六', 9, 89, 88, 100, 76, 81, 77, 95, 85, 80),
    StudentGradesBean('狗子', 10, 95, 100, 90, 72, 65, 88, 66, 79, 96),
    StudentGradesBean('丑娃', 11, 100, 67, 87, 96, 89, 69, 79, 78, 73),
    StudentGradesBean('石头', 12, 85, 75, 86, 91, 100, 66, 100, 90, 83),
    StudentGradesBean('二妞', 13, 89, 88, 100, 76, 81, 77, 95, 85, 80),
    StudentGradesBean('大妞', 14, 95, 100, 90, 72, 65, 88, 66, 79, 96),
    StudentGradesBean('黑皮', 15, 100, 67, 87, 96, 89, 69, 79, 78, 73),
    StudentGradesBean('大胆儿', 16, 85, 75, 86, 91, 100, 66, 100, 90, 83),
  ];

  List<DataRow> _dataRowList = [];

_myDataTable() {
    return DataTable(
      columns: _myDataColumnList(),
      rows: _myDataRowList(),
      dataRowHeight: 40,
      headingRowHeight: 55,
      horizontalMargin: 20,
      columnSpacing: 50,
      dividerThickness: 2,
    );
  }

 _myDataColumn(TypeBean bean) {
    return DataColumn(
      label: Text(
        bean.name,
        style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
      ),
      tooltip: '${bean.name}',
      numeric: false,
    );
  }

_myDataColumnList() {
    if (_dataColumnList.length > 0) {
      _dataColumnList.clear();
    }
    _typeList.forEach((element) {
      _dataColumnList.add(_myDataColumn(element));
    });
    return _dataColumnList;
  }

  _myDataCell(String s) {
    return DataCell(
      Text(s),
    );
  }

  _myDataRow(StudentGradesBean bean) {
    return DataRow(
      cells: [
        _myDataCell(bean.name),
        _myDataCell(bean.studentId.toString()),
        _myDataCell(bean.language.toString()),
        _myDataCell(bean.math.toString()),
        _myDataCell(bean.english.toString()),
        _myDataCell(bean.physical.toString()),
        _myDataCell(bean.chemistry.toString()),
        _myDataCell(bean.biological.toString()),
        _myDataCell(bean.geography.toString()),
        _myDataCell(bean.political.toString()),
        _myDataCell(bean.history.toString()),
      ],
    );
  }

  _myDataRowList() {
    if (_dataRowList.length > 0) {
      _dataRowList.clear();
    }
    _studentGradesList.forEach((element) {
      _dataRowList.add(_myDataRow(element));
    });
    return _dataRowList;
  }

 @override
  void initState() {
    super.initState();
    _myDataColumnList();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('DataTable'),
      ),
      body: SingleChildScrollView(
        scrollDirection: Axis.vertical,
        child: SingleChildScrollView(
          scrollDirection: Axis.horizontal,
          child: _myDataTable(),
        ),
      ),
    );
  }

7.实现列表勾选操作

  • 这里需要用到DataRow的两个属性selected,onSelectChanged
  • DataTable里面也有个属性showCheckboxColumn,这个属性如果不设置,但是设置DataRow勾选属性,一样是可以生效的,但是如果设置了false,那么DataRow勾选属性设置了也不会生效
  • 表头勾选框代表全选、全不选,这个不需要去自己实现,,DataTable自己会帮助你完成,主要就是DataTable调用的onSelectAll方法,内部会自己调用DataRow的onSelectChanged,但是如果你设置了DataTable的onSelectAll属性,那么你就要自己去实现了


    1601632272(1).png

    1601632495(1).png
selected: bean.isSelected,
onSelectChanged: (isSelected) {
  print('DataRow onSelectChanged = $isSelected');
  setState(() {
    bean.isSelected = isSelected;
  });
},

8.DataRow背景色的改变

这个需要设置属性color,可以实现勾选状态与非勾选状态下背景色的改变


1601632724(1).png
color: _MyMaterialStateColor(
        Colors.amber.value,
        isSelected: bean.isSelected,
      ),

class _MyMaterialStateColor extends MaterialStateColor {
  _MyMaterialStateColor(int defaultValue, {this.isSelected})
      : super(defaultValue);
  bool isSelected;

  @override
  Color resolve(Set<MaterialState> states) {
    if (isSelected) {
      return Colors.red;
    }
    return Colors.amber;
  }
}

9.DataTable排序

  • DataTable设置属性sortColumnIndex(以那个位置的属性排序),sortAscending(升序、降序)
    这里我们理解箭头向上代表升序,向下代表降序,那么false为升序,true为降序
  • DataColumn设置onSort属性,实现自己的排序逻辑


    升序.png
降序.png
 var _sortColumnIndex = 1;
 var _sortAscending = false;

sortColumnIndex: _sortColumnIndex,
sortAscending: _sortAscending,

onSort: (int columnIndex, bool ascending) {
  print('DataColumn columnIndex = $columnIndex ascending = $ascending');
  setState(() {
      _sortColumnIndex = columnIndex;
      _sortAscending = ascending;
    _sort();
  });
},

_sort() {
  _studentGradesList.sort((s1, s2) {
    dynamic compareA;
    dynamic compareB;
    switch (_sortColumnIndex) {
      case 0:
        compareA = s1.name;
        compareB = s2.name;
        break;
      case 1:
        compareA = s1.studentId;
        compareB = s2.studentId;
        break;
      case 2:
        compareA = s1.language;
        compareB = s2.language;
        break;
      case 3:
        compareA = s1.math;
        compareB = s2.math;
        break;
      case 4:
        compareA = s1.english;
        compareB = s2.english;
        break;
      case 5:
        compareA = s1.physical;
        compareB = s2.physical;
        break;
      case 6:
        compareA = s1.chemistry;
        compareB = s2.chemistry;
        break;
      case 7:
        compareA = s1.biological;
        compareB = s2.biological;
        break;
      case 8:
        compareA = s1.geography;
        compareB = s2.geography;
        break;
      case 9:
        compareA = s1.political;
        compareB = s2.political;
        break;
      case 10:
        compareA = s1.history;
        compareB = s2.history;
        break;
      default:
        compareA = s1.studentId;
        compareB = s2.studentId;
        _sortColumnIndex = 1;
        break;
    }
    if (!_sortAscending) {
      return compareA.compareTo(compareB);
    }
    return compareB.compareTo(compareA);
  });
}

下一节:Material组件之LinearProgressIndicator/CircularProgressIndicator

Flutter(31):Material组件之LinearProgressIndicator/CircularProgressIndicator

Flutter教学目录持续更新中

Github源代码持续更新中

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,924评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,902评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,716评论 0 239
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,783评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,166评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,510评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,784评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,476评论 0 196
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,196评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,459评论 2 243
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,978评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,321评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,964评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,046评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,803评论 0 193
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,530评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,420评论 2 265