Flutter DataTable 看這一篇就夠了

mengqingdong1發表於2020-03-04

Flutter DataTable 看這一篇就夠了

注意:無特殊說明,Flutter版本及Dart版本如下:

  • Flutter版本: 1.12.13+hotfix.5
  • Dart版本: 2.7.0

DataTable

DataTable控制元件顯示錶格資料,DataTable需要設定行和列,用法如下:

DataTable(
  columns: [
    DataColumn(label: Text('姓名')),
    DataColumn(label: Text('年齡')),
  ],
  rows: [
    DataRow(cells: [
      DataCell(Text('老孟')),
      DataCell(Text('18')),
    ]),
    
  ],
)
複製程式碼

columns引數是DataTable的列,rows引數是DataTable的每一行資料,效果如下:

![image-20200303200953329](/Users/mengqingdong/Library/Application Support/typora-user-images/image-20200303200953329.png)

在新增一行資料,只需要新增一個DataRow即可,用法如下:

DataTable(
      ...
      rows: [
        DataRow(cells: [
          DataCell(Text('老孟')),
          DataCell(Text('18')),
        ]),
        DataRow(cells: [
          DataCell(Text('大黃')),
          DataCell(Text('20')),
        ]),
      ],
    )
複製程式碼

在表頭顯示排序圖示:

DataTable(
  sortColumnIndex: 1,
  sortAscending: true,
  ...
  )
複製程式碼

sortColumnIndex參數列示表格顯示排序圖示的索引,sortAscending參數列示升序或者降序,效果如下:

Flutter DataTable 看這一篇就夠了

這裡要注意DataTable本身不能對資料進行排序,這些引數僅僅是外觀上的控制。

DataColumn

預設情況下資料是左對齊的,讓某一列右對齊只需設定DataColumn中numeric引數true,設定如下:

 DataTable(
  columns: [
    DataColumn(label: Text('姓名')),
    DataColumn(label: Text('年齡'),numeric: true),
  ],
  ...
  )
複製程式碼

效果:

Flutter DataTable 看這一篇就夠了

設定DataColumn中tooltip參數列示當長安此表頭時顯示提示,用法如下:

DataColumn(label: Text('姓名'),tooltip: '長按提示')
複製程式碼

長按提示:

Flutter DataTable 看這一篇就夠了

onSort回撥是使用者點選表頭(DataColumn)時的回撥,onSort中第一個引數columnIndex表示索引,ascending參數列示升序或者降序,用法如下:

DataColumn(label: Text('年齡'), onSort: (int columnIndex, bool ascending){
	//排序演算法
}),
複製程式碼

DataRow

可以顯示其中一行被選中,設定DataRow中selected引數為true,用法如下:

DataRow(
  selected: true,
  ...
)
複製程式碼

效果如下:

Flutter DataTable 看這一篇就夠了

onSelectChanged引數是點選每一行資料時的回撥,用法如下:

DataRow(
	onSelectChanged: (selected){
	}
	...
)
複製程式碼

設定了onSelectChanged引數,在資料的每一行和表頭的前面顯示勾選框,效果如下:

Flutter DataTable 看這一篇就夠了

當然現在點選還不能顯示選中的效果,增加選中效果,修改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> dateRows = [];
    for (int i = 0; i < data.length; i++) {
      dateRows.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: dateRows);
複製程式碼

效果如下:

Flutter DataTable 看這一篇就夠了

我們並沒有對錶頭的全選/取消全選勾選框進行控制,一個很大的疑問:點選全選/取消全選勾選框,如果都勾選了,真實資料是否也發生變化了,對應本示例就是User中的selected引數是否全部為true,可以肯定的告訴你User中的selected引數已經全部變為true了,那是如何實現的呢?非常簡單,每一行的onSelectChanged都被回撥了一次。

DataCell

DataCell是DataRow中每一個子控制元件,DataCell子控制元件不一定是文字,也可以是圖示等任意元件,我們可以給DataCell設定編輯圖示:

DataCell(Text('name'),showEditIcon: true)
複製程式碼

效果如下:

Flutter DataTable 看這一篇就夠了

當然僅僅是一個圖示,placeholder引數也是一樣的,設定為true,僅僅是文字的樣式變化了,onTap為點選回撥,用法如下:

DataCell(Text('name'),showEditIcon: true,onTap: (){
  print('DataCell onTap');
},placeholder: true)
複製程式碼

效果如下:

Flutter DataTable 看這一篇就夠了

排序

DateTable本身是沒有排序功能的,當使用者點選表頭時對資料按照本列資料進行排序,用法如下,

資料model類:

class User {
  User(this.name, this.age);

  final String name;
  final int age;
}
複製程式碼

初始化資料及預設排序:

List<User> data = [
  User('老孟', 18),
  User('老孟1', 19),
  User('老孟2', 20),
  User('老孟3', 21),
  User('老孟4', 22),
];

var _sortAscending = true;
複製程式碼

構建DataTable:

DataTable(
    sortColumnIndex: 1,
    sortAscending: _sortAscending,
    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: data.map((user) {
      return DataRow(cells: [
        DataCell(Text('${user.name}')),
        DataCell(Text('${user.age}')),
      ]);
    }).toList())
複製程式碼

效果如下:

Flutter DataTable 看這一篇就夠了

如果想給姓名列也加上排序呢,修改如下:

var _sortAscending = true;
var _sortColumnIndex =0;
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));
              }
            });
          }),
        ],
        ...
)
複製程式碼

效果如下:

Flutter DataTable 看這一篇就夠了

處理資料顯示不全問題

當表格列比較多的時候,可以使用SingleChildScrollView包裹DataTable,顯示不全時滾動顯示,用法如下:

List<DataRow> dateRows = [];
for (int i = 0; i < data.length; i++) {
  dateRows.add(DataRow(
    cells: [
      DataCell(Text('${data[i].name}')),
      DataCell(Text('${data[i].age}')),
      DataCell(Text('男')),
      DataCell(Text('2020')),
      DataCell(Text('10')),
    ],
  ));
}
return SingleChildScrollView(
  scrollDirection: Axis.horizontal,
  child: DataTable(columns: [
    DataColumn(label: Text('姓名')),
    DataColumn(
      label: Text('年齡'),
    ),
    DataColumn(
      label: Text('性別'),
    ),
    DataColumn(
      label: Text('出生年份'),
    ),
    DataColumn(
      label: Text('出生月份'),
    ),
  ], rows: dateRows),
);
複製程式碼

效果如下:

Flutter DataTable 看這一篇就夠了

今天的文章對大家是否有幫助?如果有,請在文章底部留言和點贊,以表示對我的支援,你們的留言、點贊和轉發關注是我持續更新的動力!

Flutter DataTable 看這一篇就夠了

更多相關閱讀:

相關文章