Flutter链式表格操作插件flutter_chain_table的使用

Flutter链式表格操作插件flutter_chain_table的使用

pub package

A flutter table with fixed center column list and two bi-direction tables on left and right side.

安装

运行以下命令以安装最新版本:

flutter pub add flutter_chain_table

使用

以下是ChainTable小部件的所有自定义选项:

const ChainTable({
    super.key,
    this.header,
    this.footer,
    required this.sideTableWidth,
    required this.centerColumnWidth,
    required this.leftTableColumnCount,
    required this.rightTableColumnCount,
    required this.tableRowCount,
    required this.leftBuilder,
    required this.rightBuilder,
    required this.centerBuilder,
    this.horizontalLinkedScroll,
    this.verticalLinkedScroll,
  })

示例

以下是示例项目的演示:

示例代码
import 'dart:math';

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_chain_table/flutter_chain_table.dart';
import 'package:linked_scroll_controller/linked_scroll_controller.dart';

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

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late List _testList;
  final int _price = 115;

  final LinkedScrollControllerGroup _verticalScrollControllerGroup =
      LinkedScrollControllerGroup();

  [@override](/user/override)
  void initState() {
    super.initState();
    Random random = Random();
    _testList = List.generate(50, (index) {
      return {
        'strike': index + 90,
        'call': {
          'last': random.nextInt(5) * 0.01,
          'bid': random.nextInt(5) * 0.01,
          'ask': random.nextInt(5) * 0.01,
        },
        'put': {
          'last': random.nextInt(5) * 0.01,
          'bid': random.nextInt(5) * 0.01,
          'ask': random.nextInt(5) * 0.01,
        }
      };
    });

    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      _verticalScrollControllerGroup.jumpTo(50 * 21);
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Chain Table Example'),
        ),
        body: ScrollConfiguration(
          /// 启用拖动行为以便在桌面或Web应用中使用触摸
          /// 移动设备可以不使用此功能
          behavior: ScrollConfiguration.of(context).copyWith(
            dragDevices: {
              PointerDeviceKind.touch,
              PointerDeviceKind.mouse,
            },
          ),
          child: ChainTable(
            verticalLinkedScroll: _verticalScrollControllerGroup,
            header: HeaderInfo(
              centerTableHeaderBuilder: (context, index) {
                return CellWidget(
                  'Strike',
                  backgroundColor: Colors.grey.shade200,
                );
              },
              leftTableHeaderBuilder: (context, index) {
                switch (index) {
                  case 0:
                    {
                      return const CellWidget(
                        'Last',
                      );
                    }
                  case 1:
                    {
                      return const CellWidget(
                        'Ask',
                      );
                    }

                  default:
                    {
                      return const CellWidget(
                        'Bid',
                      );
                    }
                }
              },
              rightTableHeaderBuilder: (context, index) {
                switch (index) {
                  case 0:
                    {
                      return const CellWidget('Bid');
                    }
                  case 1:
                    {
                      return const CellWidget('Ask');
                    }
                  default:
                    {
                      return const CellWidget('Last');
                    }
                }
              },
              leftTableHeaderColumnCount: 3,
              rightTableHeaderColumnCount: 3,
            ),
            footer: FooterInfo(
              centerTableFooterBuilder: (context, index) {
                return CellWidget(
                  'Strike',
                  backgroundColor: Colors.grey.shade200,
                );
              },
              leftTableFooterBuilder: (context, index) {
                switch (index) {
                  case 0:
                    {
                      return const CellWidget(
                        'Last',
                      );
                    }
                  case 1:
                    {
                      return const CellWidget(
                        'Ask',
                      );
                    }

                  default:
                    {
                      return const CellWidget(
                        'Bid',
                      );
                    }
                }
              },
              rightTableFooterBuilder: (context, index) {
                switch (index) {
                  case 0:
                    {
                      return const CellWidget('Bid');
                    }
                  case 1:
                    {
                      return const CellWidget('Ask');
                    }
                  default:
                    {
                      return const CellWidget('Last');
                    }
                }
              },
              leftTableFooterColumnCount: 3,
              rightTableFooterColumnCount: 3,
            ),
            sideTableWidth: 240,
            centerColumnWidth: 80,
            leftTableColumnCount: 3,
            rightTableColumnCount: 3,
            tableRowCount: 50,
            leftBuilder: (context, rowIndex, colIndex) {
              Color color = _testList[rowIndex]['strike'] < _price
                  ? Colors.lightBlue.shade100
                  : Colors.transparent;
              switch (colIndex) {
                case 0:
                  {
                    return CellWidget(
                      _testList[rowIndex]['call']['last'].toString(),
                      backgroundColor: color,
                    );
                  }
                case 1:
                  {
                    return CellWidget(
                      _testList[rowIndex]['call']['ask'].toString(),
                      backgroundColor: color,
                    );
                  }

                default:
                  {
                    return CellWidget(
                      _testList[rowIndex]['call']['bid'].toString(),
                      backgroundColor: color,
                    );
                  }
              }
            },
            rightBuilder: (context, rowIndex, colIndex) {
              Color color = _testList[rowIndex]['strike'] >= _price
                  ? Colors.lightBlue.shade100
                  : Colors.transparent;
              switch (colIndex) {
                case 0:
                  {
                    return CellWidget(
                      _testList[rowIndex]['put']['bid'].toString(),
                      backgroundColor: color,
                    );
                  }
                case 1:
                  {
                    return CellWidget(
                      _testList[rowIndex]['put']['ask'].toString(),
                      backgroundColor: color,
                    );
                  }

                default:
                  {
                    return CellWidget(
                      _testList[rowIndex]['put']['last'].toString(),
                      backgroundColor: color,
                    );
                  }
              }
            },
            centerBuilder: (context, index) {
              Color color = _testList[index]['strike'] == _price
                  ? Colors.lightBlue.shade300
                  : Colors.lightBlue.shade200;
              return CellWidget(
                _testList[index]['strike'].toString(),
                backgroundColor: color,
              );
            },
          ),
        ),
      ),
    );
  }
}

class CellWidget extends StatelessWidget {
  final String value;
  final Color backgroundColor;

  const CellWidget(
    this.value, {
    super.key,
    this.backgroundColor = Colors.transparent,
  });

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Container(
        color: backgroundColor,
        width: 80.0,
        height: 50,
        child: Column(
          mainAxisSize: MainAxisSize.max,
          children: [
            Flexible(
              child: Center(child: Text(value)),
            ),
            const Divider(
              height: 1.0,
              thickness: 1.0,
              color: Colors.grey,
            )
          ],
        ));
  }
}

更多关于Flutter链式表格操作插件flutter_chain_table的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter链式表格操作插件flutter_chain_table的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


flutter_chain_table 是一个用于在 Flutter 中实现链式表格操作的插件。虽然目前并没有一个官方或广泛使用的插件叫 flutter_chain_table,但你可以通过自定义实现或使用现有的 Flutter 插件来实现链式表格操作。

以下是一个可能的实现思路,假设你想要创建一个链式表格操作的插件:

1. 创建一个 ChainTable

首先,你可以创建一个 ChainTable 类,该类将负责存储表格数据并提供链式操作的方法。

class ChainTable {
  List<List<dynamic>> _data = [];

  ChainTable addRow(List<dynamic> row) {
    _data.add(row);
    return this;
  }

  ChainTable addColumn(List<dynamic> column) {
    for (int i = 0; i < column.length; i++) {
      if (i >= _data.length) {
        _data.add([]);
      }
      _data[i].add(column[i]);
    }
    return this;
  }

  ChainTable removeRow(int index) {
    if (index >= 0 && index < _data.length) {
      _data.removeAt(index);
    }
    return this;
  }

  ChainTable removeColumn(int index) {
    for (var row in _data) {
      if (index >= 0 && index < row.length) {
        row.removeAt(index);
      }
    }
    return this;
  }

  List<List<dynamic>> getData() {
    return _data;
  }
}

2. 使用 ChainTable

你可以通过链式调用来操作表格数据:

void main() {
  var table = ChainTable()
    .addRow([1, 2, 3])
    .addRow([4, 5, 6])
    .addColumn([7, 8])
    .removeRow(1)
    .removeColumn(0);

  print(table.getData()); // 输出: [[2, 3], [8]]
}

3. 创建 Flutter 插件

如果你想将这个功能封装成一个插件,你可以按照以下步骤操作:

  1. 创建插件项目

    flutter create --template=plugin flutter_chain_table
    
  2. 实现插件逻辑: 将上述 ChainTable 类复制到插件的 lib/flutter_chain_table.dart 文件中。

  3. 发布插件: 你可以将插件发布到 pub.dev 上,以便其他人可以使用。

4. 在 Flutter 项目中使用插件

pubspec.yaml 中添加依赖:

dependencies:
  flutter_chain_table: ^1.0.0

然后在你的代码中使用插件:

import 'package:flutter_chain_table/flutter_chain_table.dart';

void main() {
  var table = ChainTable()
    .addRow([1, 2, 3])
    .addRow([4, 5, 6])
    .addColumn([7, 8])
    .removeRow(1)
    .removeColumn(0);

  print(table.getData()); // 输出: [[2, 3], [8]]
}
回到顶部