一統天下 flutter - widget 列表類: DataTable - 數據表格

源碼 https://github.com/webabcd/flutter_demo
作者 webabcd

一統天下 flutter - widget 列表類: DataTable - 數據表格

示例如下:

lib\widget\list\data_table.dart

/*
 * DataTable - 數據表格
 */

import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter_demo/helper.dart';

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

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

class _DataTableDemoState extends State<DataTableDemo> {

  var _sortColumnIndex = 0;
  var _sortAscending = true;

  _getDataTable() {
    /// 數據表格
    return DataTable(
      /// 標題行 DataColumn 集合
      columns: _getDataColumnList(),
      /// 數據行 DataRow 集合
      rows: _getDataRowList(),
      
      /// 標題行的高度
      headingRowHeight: 56,
      /// 標題行的文本樣式
      headingTextStyle: const TextStyle(color: Colors.white),

      /// 數據行的高度
      dataRowHeight: 40,
      /// 數據行的文本樣式
      dataTextStyle: const TextStyle(color: Colors.white),
      /// 數據行的背景顏色
      dataRowColor: MaterialStateProperty.resolveWith((states) {
        if (states.contains(MaterialState.selected)) {
          return Colors.green;  /// 選中狀態的顏色
        }
        return Colors.red;      /// 其他狀態的顏色
      }),

      /// 列之間的間距
      columnSpacing: 56,
      /// 左側邊緣與第一列之間的間距,以及右側邊緣與最後一列之間的間距
      horizontalMargin: 10,
      /// 分隔線的寬度
      dividerThickness: 2,
      /// 最後一行數據的下面是否要顯示分隔線
      showBottomBorder: false,
      
      /// 是否在每行的左側顯示覆選框
      showCheckboxColumn: true,
      /// 複選框水平方向上的外邊距
      checkboxHorizontalMargin: 10,

      /// 當前排序的列索引
      sortColumnIndex: _sortColumnIndex,
      /// 當前排序的方向是否是正向排序
      sortAscending: _sortAscending,

      /// 點擊標題行中的全選按鈕時的回調
      /// 定義這個就要自己寫邏輯,不定義這個則走默認的全選邏輯
      /*
      onSelectAll: (value) {

      },
      */
    );
  }

  _getDataColumnList() {
    List<DataColumn> dataColumnList = [];
    for (var column in _columnList) {
      /// 標題行中的每個列
      dataColumnList.add(DataColumn(
        /// 需要顯示的內容
        label: Text(column.name,),
        /// tooltip
        tooltip: column.name,
        /// 是否右對齊
        numeric: false,
        /// 點擊標題,觸發排序操作時的回調
        onSort: (int columnIndex, bool ascending) {
          /// columnIndex - 排序的列的索引
          /// ascending - 是否正向排序
          log('onSort, columnIndex:$columnIndex, ascending:$ascending');
          if (columnIndex != 0 && columnIndex != 2) {
            return;
          }

          setState(() {
            _sortColumnIndex = columnIndex;
            _sortAscending = ascending;

            /// 對數據源排序
            _rowList.sort((p1, p2) {
              dynamic compareA;
              dynamic compareB;
              switch (_sortColumnIndex) {
                case 0:
                  compareA = p1.id;
                  compareB = p2.id;
                  break;
                case 2:
                  compareA = p1.x1;
                  compareB = p2.x1;
                  break;
              }
              if (_sortAscending) {
                return compareA.compareTo(compareB);
              }
              return compareB.compareTo(compareA);
            });
          });
        },
      ));
    }
    return dataColumnList;
  }

  _getDataRowList() {
    List<DataRow> dataRowList = [];
    for (var row in _rowList) {
      /// 數據行中的每個單元格
      dataRowList.add(DataRow(
        /// 當前行的單元格集合
        cells: [
          _getDataCell(row.id.toString()),
          _getDataCell(row.name),
          _getDataCell(row.x1.toString()),
          _getDataCell(row.x2.toString()),
          _getDataCell(row.x3.toString()),
          _getDataCell(row.x4.toString()),
          _getDataCell(row.x5.toString()),
          _getDataCell(row.x6.toString()),
          _getDataCell(row.x7.toString()),
          _getDataCell(row.x8.toString()),
        ],
        /// 當前數據行是否是選中狀態
        selected: row.isSelected,
        /// 當前數據行的選中狀態發生變化時的回調
        onSelectChanged: (isSelected) {
          setState(() {
            row.isSelected = isSelected!;
          });
        },
      ));
    }
    return dataRowList;
  }

  _getDataCell(String s) {
    /// 單元格
    return DataCell(
      Text(s),
      /// 是否在單元格上顯示編輯按鈕
      showEditIcon: false,
      /// 單擊事件,類似的有 onTap, onLongPress, onTapDown, onDoubleTap, onTapCancel
      onTap: () {
        log("onTap");
      }
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('title'),),
      backgroundColor: Colors.orange,
      /// DataTable 不支持滾動,需要藉助 SingleChildScrollView 實現滾動
      body: SingleChildScrollView(
        scrollDirection: Axis.vertical,
        child: SingleChildScrollView(
          scrollDirection: Axis.horizontal,
          /// 這個主題用於修改排序的提示圖標的顏色,其它的一些無法直接修改的樣式也可以通過這種方式修改,具體用的是什麼主題可以看源代碼
          child: Theme(
            data: ThemeData(
              iconTheme: const IconThemeData(
                color: Colors.blue,
              ),
            ),
            child: _getDataTable(),
          ),
        ),
      ),
    );
  }
}

class _MyColumn {
  const _MyColumn({required this.name});

  final String name;
}

class _MyRow {
  int id;
  String name;
  int x1;
  int x2;
  int x3;
  int x4;
  int x5;
  int x6;
  int x7;
  int x8;
  bool isSelected;

  _MyRow(
      this.id,
      this.name,
      this.x1,
      this.x2,
      this.x3,
      this.x4,
      this.x5,
      this.x6,
      this.x7,
      this.x8, {
        this.isSelected = false,
      });
}

var _columnList = const [
  _MyColumn(name: '學號'),
  _MyColumn(name: '姓名'),
  _MyColumn(name: '學科1'),
  _MyColumn(name: '學科2'),
  _MyColumn(name: '學科3'),
  _MyColumn(name: '學科4'),
  _MyColumn(name: '學科5'),
  _MyColumn(name: '學科6'),
  _MyColumn(name: '學科7'),
  _MyColumn(name: '學科8'),
];

var _random = Random();
var _rowList = List<_MyRow>.generate(30, (index) =>
    _MyRow(index, 'name$index', _random.nextInt(100), _random.nextInt(100), _random.nextInt(100), _random.nextInt(100), _random.nextInt(100), _random.nextInt(100), _random.nextInt(100), _random.nextInt(100)),);

源碼 https://github.com/webabcd/flutter_demo
作者 webabcd

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章