Flutter可扩展数据表格插件expandable_datatable_2的使用

Flutter可扩展数据表格插件expandable_datatable_2的使用

ExpandableDataTable 是一个用于在 Flutter 中处理数据表显示和编辑的库。它可以支持行排序、灵活的列大小、可展开的行、分页、可编辑的行、自定义编辑对话框、自定义分页小部件以及自定义扩展内容。

特性

  • 行排序
  • 灵活的列大小
  • 可展开的行
  • 分页
  • 可编辑的行
  • 自定义编辑对话框
  • 自定义分页小部件
  • 自定义扩展内容
  • 行和头部列的样式

ExpandableDataTable 参数

名称 描述
headers 数据列的头部列表
rows 要显示的数据行列表
visibleColumnCount 显示在头部的列数
multipleExpansion 是否启用多行展开
isEditable 行是否可编辑
onRowChanged 当行通过编辑对话框更改时调用的回调函数
onPageChanged 当分页更改时调用的回调函数
renderEditDialog 构建自定义编辑对话框的小部件渲染函数
renderCustomPagination 构建自定义分页小部件的渲染函数
renderExpansionContent 构建所有行的自定义扩展容器的渲染函数

ExpandableThemeData 参数

名称 描述
headerTextStyle 头部行的文本样式
rowTextStyle 所有行的文本样式
contentPadding 所有头部和数据行的填充
headerTextMaxLines 头部文本最多显示的行数
rowTextMaxLines 行文本最多显示的行数
rowTextOverflow 行单元格文本的视觉溢出样式
expandedTextStyle 扩展内容的文本样式
headerColor 头部行的背景色
headerSortIconColor 头部排序箭头图标的颜色
headerHeight 头部小部件的高度
expandedBorderColor 扩展边框的颜色
rowColor 行的背景色
evenRowColor 偶数索引行的背景色
oddRowColor 奇数索引行的背景色
rowBorder 所有行的边框样式
editIcon 显示编辑功能的图标
expansionIcon 展开扩展内容的图标
paginationSize 默认分页小部件的大小
paginationTextStyle 默认分页小部件页面数字的文本样式
paginationSelectedTextColor 默认分页小部件选中单元格的页面数字颜色
paginationUnselectedTextColor 默认分页小部件未选中单元格的页面数字颜色
paginationSelectedFillColor 默认分页小部件选中单元格的背景填充颜色
paginationBorderColor 默认分页小部件的边框颜色
paginationBorderRadius 默认分页小部件的边框半径值
paginationBorderWidth 默认分页小部件的边框宽度值

使用方法

1. 添加依赖

pubspec.yaml 文件中添加 expandable_datatable 作为依赖项。

dependencies:
  expandable_datatable: ^1.0.0

2. 导入包

在你的 Dart 文件中导入 expandable_datatable 包。

import 'package:expandable_datatable/expandable_datatable.dart';

3. 创建数据

创建用于数据表的头部列表和行列表。

List<ExpandableColumn<dynamic>> headers = [
  ExpandableColumn<int>(columnTitle: "ID", columnFlex: 1),
  ExpandableColumn<String>(columnTitle: "First name", columnFlex: 2),
  ExpandableColumn<String>(columnTitle: "Last name", columnFlex: 2),
  ExpandableColumn<String>(columnTitle: "Maiden name", columnFlex: 2),
  ExpandableColumn<int>(columnTitle: "Age", columnFlex: 1),
  ExpandableColumn<String>(columnTitle: "Gender", columnFlex: 2),
  ExpandableColumn<String>(columnTitle: "Email", columnFlex: 4),
];

List<ExpandableRow> rows = userList.map<ExpandableRow>((e) {
  return ExpandableRow(cells: [
    ExpandableCell<int>(columnTitle: "ID", value: e.id),
    ExpandableCell<String>(columnTitle: "First name", value: e.firstName),
    ExpandableCell<String>(columnTitle: "Last name", value: e.lastName),
    ExpandableCell<String>(columnTitle: "Maiden name", value: e.maidenName),
    ExpandableCell<int>(columnTitle: "Age", value: e.age),
    ExpandableCell<String>(columnTitle: "Gender", value: e.gender),
    ExpandableCell<String>(columnTitle: "Email", value: e.email),
  ]);
}).toList();

4. 构建数据表格

build 方法中构建 ExpandableDataTable 小部件。

void createDataSource() {...}

[@override](/user/override)
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: const Text("Expandable Datatable Example"),
    ),
    body: ExpandableTheme(
      data: ExpandableThemeData(
        context,
        rowBorder: const BorderSide(color: Colors.amber),
        expandedBorderColor: Colors.transparent,
        paginationSize: 48,
      ),
      child: ExpandableDataTable(
        rows: rows,
        headers: headers,
        visibleColumnCount: 4,
      ),
    ),
  );
}

示例代码

以下是一个完整的示例代码,展示了如何使用 expandable_datatable 插件。

import 'dart:convert';

import 'package:expandable_datatable/expandable_datatable.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import 'model/models.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: const HomePage(),
      theme: ThemeData.light(),
    );
  }
}

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

  [@override](/user/override)
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List<Users> userList = [];

  late List<ExpandableColumn<dynamic>> headers;
  late List<ExpandableRow> rows;

  bool _isLoading = true;

  void setLoading() {
    setState(() {
      _isLoading = false;
    });
  }

  [@override](/user/override)
  void initState() {
    super.initState();

    fetch();
  }

  void fetch() async {
    userList = await getUsers();

    createDataSource();

    setLoading();
  }

  Future<List<Users>> getUsers() async {
    final String response = await rootBundle.loadString('asset/dumb.json');

    final data = await json.decode(response);

    API apiData = API.fromJson(data);

    if (apiData.users != null) {
      return apiData.users!;
    }

    return [];
  }

  void createDataSource() {
    headers = [
      ExpandableColumn<int>(columnTitle: "ID", columnFlex: 1),
      ExpandableColumn<String>(columnTitle: "First name", columnFlex: 2),
      ExpandableColumn<String>(columnTitle: "Last name", columnFlex: 2),
      ExpandableColumn<String>(columnTitle: "Maiden name", columnFlex: 2),
      ExpandableColumn<int>(columnTitle: "Age", columnFlex: 1),
      ExpandableColumn<String>(columnTitle: "Gender", columnFlex: 1),
      ExpandableColumn<String>(columnTitle: "Email", columnFlex: 4),
    ];

    rows = userList.map<ExpandableRow>((e) {
      return ExpandableRow(cells: [
        ExpandableCell<int>(columnTitle: "ID", value: e.id),
        ExpandableCell<String>(columnTitle: "First name", value: e.firstName),
        ExpandableCell<String>(columnTitle: "Last name", value: e.lastName),
        ExpandableCell<String>(columnTitle: "Maiden name", value: e.maidenName),
        ExpandableCell<int>(columnTitle: "Age", value: e.age),
        ExpandableCell<String>(columnTitle: "Gender", value: e.gender),
        ExpandableCell<String>(columnTitle: "Email", value: e.email),
      ]);
    }).toList();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: !_isLoading
            ? LayoutBuilder(builder: (context, constraints) {
                int visibleCount = 3;
                if (constraints.maxWidth < 600) {
                  visibleCount = 3;
                } else if (constraints.maxWidth < 800) {
                  visibleCount = 4;
                } else if (constraints.maxWidth < 1000) {
                  visibleCount = 5;
                } else {
                  visibleCount = 6;
                }

                return ExpandableTheme(
                  data: ExpandableThemeData(
                    context,
                    contentPadding: const EdgeInsets.all(20),
                    expandedBorderColor: Colors.transparent,
                    paginationSize: 48,
                    headerHeight: 56,
                    headerColor: Colors.amber[400],
                    headerBorder: const BorderSide(
                      color: Colors.black,
                      width: 1,
                    ),
                    evenRowColor: const Color(0xFFFFFFFF),
                    oddRowColor: Colors.amber[200],
                    rowBorder: const BorderSide(
                      color: Colors.black,
                      width: 0.3,
                    ),
                    rowColor: Colors.green,
                    headerTextMaxLines: 4,
                    headerSortIconColor: const Color(0xFF6c59cf),
                    paginationSelectedFillColor: const Color(0xFF6c59cf),
                    paginationSelectedTextColor: Colors.white,
                  ),
                  child: ExpandableDataTable(
                    headers: headers,
                    rows: rows,
                    multipleExpansion: false,
                    isEditable: false,
                    onRowChanged: (newRow) {
                      print(newRow.cells[01].value);
                    },
                    onPageChanged: (page) {
                      print(page);
                    },
                    renderEditDialog: (row, onSuccess) => _buildEditDialog(row, onSuccess),
                    visibleColumnCount: visibleCount,
                  ),
                );
              })
            : const Center(child: CircularProgressIndicator()),
      ),
    );
  }

  Widget _buildEditDialog(
      ExpandableRow row, Function(ExpandableRow) onSuccess) {
    return AlertDialog(
      title: SizedBox(
        height: 300,
        child: TextButton(
          child: const Text("Change name"),
          onPressed: () {
            row.cells[1].value = "x3";
            onSuccess(row);
          },
        ),
      ),
    );
  }
}

更多关于Flutter可扩展数据表格插件expandable_datatable_2的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter可扩展数据表格插件expandable_datatable_2的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


expandable_datatable_2 是一个用于 Flutter 的可扩展数据表格插件。它允许你创建具有可扩展行的表格,类似于树形结构,用户可以通过点击行来展开或折叠子行。这个插件非常适合展示层次结构的数据。

安装

首先,你需要在 pubspec.yaml 文件中添加 expandable_datatable_2 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  expandable_datatable_2: ^latest_version

然后运行 flutter pub get 来安装依赖。

基本用法

以下是一个简单的示例,展示如何使用 expandable_datatable_2 插件创建一个可扩展的数据表格。

import 'package:flutter/material.dart';
import 'package:expandable_datatable_2/expandable_datatable_2.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Expandable DataTable Example'),
        ),
        body: ExpandableDataTableExample(),
      ),
    );
  }
}

class ExpandableDataTableExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: ExpandableDataTable(
        headers: [
          ExpandableColumn(columnName: 'Name'),
          ExpandableColumn(columnName: 'Age'),
          ExpandableColumn(columnName: 'Role'),
        ],
        rows: [
          ExpandableRow(
            cells: [
              {'columnName': 'Name', 'value': 'John Doe'},
              {'columnName': 'Age', 'value': '30'},
              {'columnName': 'Role', 'value': 'Developer'},
            ],
            children: [
              ExpandableRow(
                cells: [
                  {'columnName': 'Name', 'value': 'Jane Smith'},
                  {'columnName': 'Age', 'value': '25'},
                  {'columnName': 'Role', 'value': 'Designer'},
                ],
              ),
              ExpandableRow(
                cells: [
                  {'columnName': 'Name', 'value': 'Mike Johnson'},
                  {'columnName': 'Age', 'value': '28'},
                  {'columnName': 'Role', 'value': 'Tester'},
                ],
              ),
            ],
          ),
          ExpandableRow(
            cells: [
              {'columnName': 'Name', 'value': 'Alice Brown'},
              {'columnName': 'Age', 'value': '35'},
              {'columnName': 'Role', 'value': 'Manager'},
            ],
          ),
        ],
      ),
    );
  }
}

参数说明

  • headers: 定义表格的列头,每个列头由 ExpandableColumn 表示。
  • rows: 定义表格的行数据,每个行由 ExpandableRow 表示。ExpandableRow 可以包含子行,用于实现可扩展功能。
  • cells: 定义行中的单元格数据,每个单元格是一个 Map,包含 columnNamevalue
  • children: 定义当前行的子行,用于实现可扩展功能。

自定义样式

你可以通过 ExpandableDataTable 的参数来自定义表格的样式,例如:

ExpandableDataTable(
  headers: [
    ExpandableColumn(columnName: 'Name'),
    ExpandableColumn(columnName: 'Age'),
    ExpandableColumn(columnName: 'Role'),
  ],
  rows: [
    // Rows here
  ],
  headerDecoration: BoxDecoration(
    color: Colors.blue,
    borderRadius: BorderRadius.circular(5),
  ),
  headerTextStyle: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
  rowDecoration: BoxDecoration(
    color: Colors.grey[200],
    border: Border(bottom: BorderSide(color: Colors.grey[300]!)),
  ),
  rowTextStyle: TextStyle(color: Colors.black87),
  expandedRowDecoration: BoxDecoration(
    color: Colors.grey[100],
  ),
  expandedRowTextStyle: TextStyle(color: Colors.black54),
);
回到顶部