Flutter入门(40):Flutter 组件之 DataTable 详解

1. 基本介绍

DataTable 是 flutter 提供的一个表格控件,不是很复杂。

2. 示例代码

代码下载地址。如果对你有帮助的话记得给个关注,代码会根据我的 Flutter 专题不断更新。

3. Tooltip 属性介绍

DataTable 属性 介绍
columns @required 列数组
sortColumnIndex 有排列箭头的列,仅仅是展示箭头
sortAscending 是否升序,默认为 true, 排列顺序,仅仅是箭头向上还是向下
onSelectAll 左上角全选按钮点击回调
dataRowHeight Rows 中每条 Row 高度,默认为 kMinInteractiveDimension = 48.0
headingRowHeight 顶部 Row 高度,默认为 56.0
horizontalMargin 左侧边距,默认为 24.0
columnSpacing 每一列间距,默认为 56.0
showCheckboxColumn 是否展示左侧 checkbox 这一列,默认为 true
dividerThickness 分割线宽度,默认为 1.0
rows @required 行数组
DataColumn 属性 介绍
label 文本
tooltip 长按提示
numeric 是否居右,默认为 false
onSort 点击排序箭头回调函数
DataRow 属性 介绍
selected checkbox 是否选中,默认为 false
onSelectChanged 左侧 checkbox 点击事件
color DataRow 颜色回调函数
cells 数组
DataCell 属性 介绍
child 子控件
placeholder 是否为 placeholder,会改变 Text 样式
showEditIcon 是否展示编辑按钮
onTap 点击事件

4. DataTable 详解

DataTable 较为简单,属性也比较少,代码备注很清晰。

4.1 示例代码

import 'package:flutter/material.dart';

class FMDataTableVC extends StatefulWidget{
  @override
  FMDataTableState createState() => FMDataTableState();
}

class FMDataTableState extends State  {
  List  _datas = [];
  bool _sortAscending = false;

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

    initData();
  }

  void initData(){
    _datas.clear();

    _datas.add(DataRowModel("提莫", "射手", "6", "1888"));
    _datas.add(DataRowModel("盖伦", "战士", "8", "2300"));
    _datas.add(DataRowModel("剑圣", "刺客", "10", "2600"));
    _datas.add(DataRowModel("劫", "刺客", "18", "3333"));
    _datas.add(DataRowModel("慎", "坦克", "12", "2800"));
    _datas.add(DataRowModel("盲僧", "刺客", "16", "3000"));
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(title: Text("DataTable"),),
      body: SingleChildScrollView(
        scrollDirection: Axis.horizontal,
        child: _dataTable(),
      ),
    );
  }
  
  DataTable _dataTable(){
    return DataTable(
      sortColumnIndex: 2, // 有排列箭头的列,仅仅是展示箭头
      sortAscending: _sortAscending, // 排列顺序,仅仅是箭头向上还是向下
      // 左上角全选按钮点击回调
      onSelectAll: (boolValue){
        print("onSelectAll");
      },
      dataRowHeight: 60, // Rows 中每条 Row 高度
      headingRowHeight: 100, // 顶部 Row 高度
      horizontalMargin: 20, // 左侧边距
      columnSpacing: 100, // 每一列间距
      showCheckboxColumn: true, // 是否展示左侧 checkbox,默认为 true,设置为 false,最左侧不展示 checkbox
      dividerThickness: 3, // 分割线宽度

      // 列数组 
      columns: _dataColumns(),
      // 行数组 
      rows: _dataRows(),

    );
  }

  List  _dataColumns(){
    List  columns = [];
    columns.add(DataColumn(label: Text("名字")));
    columns.add(DataColumn(label: Text("类型")));
    columns.add(
        DataColumn(
          label: Text("等级"), // 文本
          tooltip: "这代表英雄的等级", // 长按提示
          numeric: true, // 是否居右,默认为 false
          // 点击排序箭头回调函数
          onSort: (index, booValue){
            print("index = $index, booValue = $booValue");
          },
        )
    );
    columns.add(DataColumn(label: Text("战力")));
    return columns;
  }

  List  _dataRows(){
    List  rows = [];
    _datas.forEach((row) {
      rows.add(DataRow(
        cells: [
          DataCell(Text("${row.name}")),
          DataCell(Text("${row.type}")),
          DataCell(Text("${row.level}")),
          DataCell(
            // 子控件
            Text("${row.zhanli}"),
            // TextField(
            //   controller: TextEditingController(
            //     text: "${row.zhanli}"
            //   ),
            // ),
            // 点击事件
            onTap: (){
              print("DataCell.onTap");
            },
            placeholder: true, // 是否是 placeholder,默认为 false,设置为 true 时 Text 会变成灰色 placeholder
            showEditIcon: true, // 是否展示编辑图标
          ),
        ],
        // 左侧 checkbox 点击事件
        onSelectChanged: (changed){
          row.onSelected = changed;
          setState(() {

          });
        },
        // 左侧 checkbox 是否选中
        selected: row.onSelected,
        // DataRow 颜色回调函数
        color: MaterialStateProperty.resolveWith((states){
          if(states.contains(MaterialState.selected)){
            return Colors.red.shade100;
          }
          return Colors.grey.shade100;
        }),
      ));
    });
    return rows;
  }
}

class DataRowModel {
  String name;
  String type;
  String zhanli;
  String level;
  bool onSelected = false;

  DataRowModel(this.name, this.type, this.level, this.zhanli);
}
DataTable.gif

4.2 排序处理

示例中,点击 升序 箭头并不会自动排序,并且默认顺序也是不对的。其实在 DataTable 提供的属性中,仅仅是一个箭头展示效果和点击事件而已,如果需要点击切换排序,还需要自定义代码来排序,然后刷新页面才可以。

  List  _dataColumns(){
    List  columns = [];
    columns.add(DataColumn(label: Text("名字")));
    columns.add(DataColumn(label: Text("类型")));
    columns.add(
        DataColumn(
          label: Text("等级"), // 文本
          tooltip: "这代表英雄的等级", // 长按提示
          numeric: false, // 是否居右,默认为 false
          // 点击排序箭头回调函数
          onSort: (index, ascend){
            print("index = $index, booValue = $ascend");

            if (ascend) {
              _datas.sort((a, b) => (int.parse(a.level)).compareTo(int.parse(b.level)));
            } else {
              _datas.sort((a, b) => (int.parse(b.level)).compareTo(int.parse(a.level)));
            }

            setState(() {
              _sortAscending = ascend;
            });
          },
        )
    );
    columns.add(DataColumn(label: Text("战力")));
    return columns;
  }

此处注意,我们的 level 用的是 String 类型,如果不转换直接比较,排序会出现问题。

DataTable sort.gif

5. 技术小结

DataTable 属性较少,稍微练习一下很好掌握,反正也不是啥特别常用的控件。

你可能感兴趣的:(Flutter入门(40):Flutter 组件之 DataTable 详解)