10、 Flutter Widgets 之 DataTable表格数据

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来完成纵向横向的滑动

  • /**
     * @Author wywinstonwy
     * @Date 2021/12/28 9:45 下午
     * @Description:
     */
    import 'package:demo202112/utils/common_appbar.dart';
    import 'package:flutter/material.dart';
    
     class WyDataTable extends StatefulWidget {
       const WyDataTable({Key? key}) : super(key: key);
    
       @override
       _WyDataTableState createState() => _WyDataTableState();
     }
    
     class _WyDataTableState extends State<WyDataTable> {
       @override
       Widget build(BuildContext context) {
         return Scaffold(
           appBar: getAppBar('DataTable'),
           body: _baseDataTable(),
         );
       }
       _baseDataTable(){
         return DataTable(
           columns: [
             DataColumn(label: Text('姓名')),
             DataColumn(label: Text('年龄')),
           ],
           rows: [
             DataRow(cells: [
               DataCell(Text('老王')),
               DataCell(Text('26')),
             ]),
             DataRow(cells: [
               DataCell(Text('老李')),
               DataCell(Text('16')),
             ]),
             DataRow(cells: [
               DataCell(Text('老李')),
               DataCell(Text('16')),
             ]),
           ],
         );
       }
     }
    

    效果:

    在表头显示排序图标:

    DataTable(
      sortColumnIndex: 1,
      sortAscending: true,
      ...
      )

     sortColumnIndex参数表示表格显示排序图标的索引,sortAscending参数表示升序或者降序,效果如下:

     

DataColumn


默认情况下数据是左对齐的,让某一列右对齐只需设置DataColumn中numeric参数true,设置如下:

 DataTable(
  columns: [
    DataColumn(label: Text('姓名')),
    DataColumn(label: Text('年龄'),numeric: true),
  ],
  ...
  )

设置DataColumn中tooltip参数表示当长按此表头时显示提示,用法如下: 

DataColumn(label: Text('姓名'),tooltip: '长按提示')

 onSort回调是用户点击表头(DataColumn)时的回调,onSort中第一个参数columnIndex表示索引,ascending参数表示升序或者降序,用法如下:

DataColumn(label: Text('年龄'), onSort: (int columnIndex, bool ascending){
    //排序算法
}),

DataRow 


可以显示其中一行被选中,设置DataRow中selected参数为true,用法如下:

DataRow(
  selected: true,
  ...
)

效果:

 onSelectChanged参数是点击每一行数据时的回调,用法如下:

DataRow(
    onSelectChanged: (selected){
    }
    ...
)

设置了onSelectChanged参数,在数据的每一行和表头的前面显示勾选框,效果如下:

 当然现在点击还不能显示选中的效果,增加选中效果,修改User model类,增加selected属性,表示当前行是否选中:

class User {
  User(this.name, this.age, {this.selected = false});

  String name;
  int age;
  bool selected;
}

修改数据:

List<User> data = [
     User('老往', 18),
     User('老李1', 19,selected: true),
     User('老张2', 20),
     User('老舍3', 21),
     User('老牛4', 22),
   ];

构建DataTable:

   List<DataRow> dataRows = [];
     for(int i=0;i<data.length;i++){
       dataRows.add(DataRow(
          selected: data[i].selected,
           onSelectChanged: (selected){
            setState(() {
              data[i].selected = selected!;
            });
           },
           cells: [
             DataCell(Text('${data[i].name}')),
             DataCell(Text('${data[i].age}')),
           ]));
     }
     return DataTable(
         columns: [
           DataColumn(label: Text('姓名')),
           DataColumn(label: Text('年龄')),
         ],
         rows: dataRows);
   }

效果:

 我们并没有对表头的全选/取消全选勾选框进行控制,一个很大的疑问:点击全选/取消全选勾选框,如果都勾选了,真实数据是否也发生变化了,对应本示例就是User中的selected参数是否全部为true,可以肯定的告诉你User中的selected参数已经全部变为true了,那是如何实现的呢?非常简单,每一行的onSelectChanged都被回调了一次。

DataCell


 DataCell是DataRow中每一个子控件,DataCell子控件不一定是文本,也可以是图标等任意组件,我们可以给DataCell设置编辑图标:

             DataCell(Text('${data[i].age}'),showEditIcon: true),

效果:

 当然仅仅是一个图标,placeholder参数也是一样的,设置为true,仅仅是文字的样式变化了,onTap为点击回调,用法如下:

 DataCell(Text('${data[i].age}'),showEditIcon: true,onTap: (){
               print('${data[i].age}');
             },placeholder: true),

排序 


DateTable本身是没有排序功能的,当用户点击表头时对数据按照本列数据进行排序,用法如下,

数据model类:

/**
 * @Author wywinstonwy
 * @Date 2021/12/28 9:45 下午
 * @Description:
 */
import 'package:demo202112/utils/common_appbar.dart';
import 'package:flutter/material.dart';

 class WyDataTable extends StatefulWidget {
   const WyDataTable({Key? key}) : super(key: key);

   @override
   _WyDataTableState createState() => _WyDataTableState();
 }

 class _WyDataTableState extends State<WyDataTable> {
   List<User> data = [
     User('老往', 18),
     User('老李1', 19,selected: true),
     User('老张2', 20),
     User('老舍3', 21),
     User('老牛4', 22),
   ];
   var _sortAscending = true;
   @override
   Widget build(BuildContext context) {
     return Scaffold(
       appBar: getAppBar('DataTable'),
       body: _buildDataRows(),
     );
   }
   _baseDataTable(){
     return DataTable(
       sortColumnIndex: 1,
       sortAscending: true,
       columns: [
         DataColumn(label: Text('姓名'),tooltip: '长按提示'),
         DataColumn(label: Text('年龄'),numeric: true,onSort: (int columnIndex,bool ascending){
           //排序算法

         }),
       ],
       rows: [
         DataRow(cells: [
           DataCell(Text('老王')),
           DataCell(Text('26')),
         ]),
         DataRow(
           selected: true,
             onSelectChanged: (selected){
             print(selected);
             },
             cells: [
           DataCell(Text('老李')),
           DataCell(Text('16')),
         ]),
         DataRow(cells: [
           DataCell(Text('老李')),
           DataCell(Text('16')),
         ]),
       ],
     );
   }
   _buildDataRows(){
     List<DataRow> dataRows = [];
     for(int i=0;i<data.length;i++){
       dataRows.add(DataRow(
          selected: data[i].selected,
           onSelectChanged: (selected){
            setState(() {
              data[i].selected = selected!;
            });
           },
           cells: [
             DataCell(Text('${data[i].name}')),
             DataCell(Text('${data[i].age}')
             ),
           ]));
     }
     return DataTable(
         sortColumnIndex: 1,
         sortAscending: true,
         columns: [
           DataColumn(label: Text('姓名')),
           DataColumn(label: Text('年龄'),onSort: (int columnIndex,bool ascending){
             setState(() {
               _sortAscending = ascending;
               if(ascending){
                 data.sort((a,b)=>a.age.compareTo(b.age));
               }else{
                 data.sort((a, b) => b.age.compareTo(a.age));
               }
             });
           }),
         ],
         rows: dataRows);
   }
 }

class User {
  User(this.name, this.age, {this.selected = false});

  String name;
  int age;
  bool selected;
}

 处理数据显示不全问题


当表格列比较多的时候,可以使用SingleChildScrollView包裹DataTable,显示不全时滚动显示,用法如下:

 _buildDataRows(){
     List<DataRow> dataRows = [];
     for(int i=0;i<data.length;i++){
       dataRows.add(DataRow(
          selected: data[i].selected,
           onSelectChanged: (selected){
            setState(() {
              data[i].selected = selected!;
            });
           },
           cells: [
             DataCell(Text('${data[i].name}')),
             DataCell(Text('${data[i].age}'),),
             DataCell(Text('${data[i].address}'),),
             DataCell(Text('${data[i].birthday}'),),
             DataCell(Text('${data[i].birthday1}'),),
           ]));
     }
     return SingleChildScrollView(
       scrollDirection: Axis.horizontal,
       child: DataTable(
           sortColumnIndex: 1,
           sortAscending: true,
           columns: [
             DataColumn(label: Text('姓名')),
             DataColumn(label: Text('年龄'),onSort: (int columnIndex,bool ascending){
               setState(() {
                 _sortAscending = ascending;
                 if(ascending){
                   data.sort((a,b)=>a.age.compareTo(b.age));
                 }else{
                   data.sort((a, b) => b.age.compareTo(a.age));
                 }
               });
             }),
             DataColumn(label: Text('地址')),
             DataColumn(label: Text('出身日期')),
             DataColumn(label: Text('出身日期')),

           ],
           rows: dataRows),
     );
   }

猜你喜欢

转载自blog.csdn.net/wywinstonwy/article/details/122203608#comments_22550284
今日推荐