Flutter网格布局插件flex_grid的使用

发布于 1周前 作者 htzhanglong 来自 Flutter

Flutter网格布局插件 flex_grid 的使用

flex_grid 是一个功能强大的Flutter插件,用于在表格格式中快速显示数据。它支持冻结列/行、加载更多数据、高性能渲染,并且在 TabBarViewPageView 中有更好的用户体验。

主要特性

  • 冻结列/行
  • 支持加载更多数据
  • 高性能渲染
  • 适用于 TabBarViewPageView

示例效果

冻结列/行 TabView 大量数据
FrozenedRowColumn TabView HugeData
Excel风格 股票列表 -
Excel StockList -

参数说明

参数 描述 默认值
frozenedColumnsCount 冻结的列数 0
frozenedRowsCount 冻结的行数 0
cellBuilder 单元格构建器 必填
columnsCount 列的数量 必填
source 数据源 必填
rowWrapper 行装饰回调 null
rebuildCustomScrollView 当数据源变化时是否重建 false
controller 垂直方向滚动控制器 null
horizontalController 水平方向同步控制器 null
outerHorizontalSyncController 外部水平方向同步控制器 null
physics 滚动物理属性 null
verticalHighPerformance / horizontalHighPerformance 是否强制子项在滚动方向上具有固定的大小 false
headerStyle 表头样式 CellStyle.header()
cellStyle 单元格样式 CellStyle.cell()
indicatorBuilder 加载状态指示器构建器 null
extendedListDelegate 扩展代理 null
headersBuilder 自定义表头构建器 null
link 是否链接父级 ExtendedTabView false

数据源 (source)

FlexGrid.source 来自 loading_more_listLoadingMoreBase 是用于加载更多数据的数据集合。你需要重写 loadData 方法来加载数据,并在没有更多数据时将 hasMore 设置为 false

class FlexGridSource extends LoadingMoreBase<GridRow> {
  int _pageIndex = 1;

  void _load() {
    for (int i = 0; i < 15; i++) {
      add(GridRow(name: 'index:$_pageIndex-$i'));
    }
  }

  [@override](/user/override)
  bool get hasMore => _pageIndex < 4;

  [@override](/user/override)
  Future<bool> loadData([bool isloadMoreAction = false]) async {
    await Future<void>.delayed(const Duration(seconds: 2));
    _load();
    _pageIndex++;
    return true;
  }

  [@override](/user/override)
  Future<bool> refresh([bool notifyStateChanged = false]) async {
    _pageIndex = 1;
    return super.refresh(notifyStateChanged);
  }
}

行装饰 (rowWrapper)

你可以通过 rowWrapper 回调来装饰每一行的控件。

FlexGrid(
  rowWrapper: (
    BuildContext context,
    T data,
    int row,
    Widget child,
  ) {
    return Column(
      children: <Widget>[
        child,
        const Divider(),
      ],
    );
  },
);

自定义表头 (headersBuilder)

你可以在 headersBuilder 回调中添加自定义的表头。

FlexGrid(
  headersBuilder: (BuildContext b, Widget header) {
    return <Widget>[
      header,
      SliverToBoxAdapter(
        child: PullToRefreshContainer((PullToRefreshScrollNotificationInfo info) {
          return PullToRefreshHeader(info, source.lastRefreshTime);
        }),
      ),
    ];
  },
);

完整示例 Demo

以下是一个完整的 flex_grid 使用示例:

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'FlexGrid Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  [@override](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final FlexGridSource _source = FlexGridSource();

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('FlexGrid Example'),
      ),
      body: FlexGrid<FlexGridSource>(
        source: _source,
        columnsCount: 3,
        frozenedColumnsCount: 1,
        frozenedRowsCount: 1,
        cellBuilder: (BuildContext context, int column, int row, FlexGridSource source) {
          if (row == 0 && column == 0) {
            return Container(
              padding: EdgeInsets.all(8.0),
              color: Colors.grey[300],
              child: Text('Frozen Header'),
            );
          } else if (row == 0) {
            return Container(
              padding: EdgeInsets.all(8.0),
              color: Colors.grey[300],
              child: Text('Header ${column + 1}'),
            );
          } else if (column == 0) {
            return Container(
              padding: EdgeInsets.all(8.0),
              color: Colors.grey[200],
              child: Text('Row ${row + 1}'),
            );
          } else {
            return Container(
              padding: EdgeInsets.all(8.0),
              child: Text('Item ${row + 1}-${column + 1}'),
            );
          }
        },
        headerStyle: CellStyle(headerColor: Colors.grey[300]),
        cellStyle: CellStyle(cellColor: Colors.white),
      ),
    );
  }
}

更多关于Flutter网格布局插件flex_grid的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter网格布局插件flex_grid的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter中使用flex_grid插件来实现网格布局的示例代码。flex_grid是一个方便的插件,用于在Flutter应用中创建响应式的网格布局。

首先,确保你已经在pubspec.yaml文件中添加了flex_grid依赖:

dependencies:
  flutter:
    sdk: flutter
  flex_grid: ^x.y.z  # 替换为最新版本号

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

接下来是一个使用flex_grid的简单示例:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'FlexGrid Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('FlexGrid Demo'),
      ),
      body: GridView.builder(
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2, // 网格列数
          crossAxisSpacing: 8.0,
          mainAxisSpacing: 8.0,
        ),
        itemCount: 20, // 网格项数量
        itemBuilder: (BuildContext context, int index) {
          return Card(
            child: FlexGrid(
              columns: 2, // 子网格列数
              gap: 8.0,
              children: [
                FlexGridItem(
                  child: Container(
                    color: Colors.red,
                    child: Center(child: Text('Item 1')),
                  ),
                ),
                FlexGridItem(
                  child: Container(
                    color: Colors.green,
                    child: Center(child: Text('Item 2')),
                  ),
                ),
                FlexGridItem(
                  child: Container(
                    color: Colors.blue,
                    child: Center(child: Text('Item 3')),
                  ),
                ),
                FlexGridItem(
                  child: Container(
                    color: Colors.yellow,
                    child: Center(child: Text('Item 4')),
                  ),
                ),
              ],
            ),
          );
        },
      ),
    );
  }
}

在这个示例中,我们做了以下几件事:

  1. 依赖安装:在pubspec.yaml文件中添加了flex_grid依赖。
  2. 基础布局:使用MaterialAppScaffold来创建一个基本的Flutter应用结构。
  3. 网格视图:使用GridView.builder来创建一个包含多个网格项的视图。这里我们将每个网格项设置为一个Card,并在Card内部使用FlexGrid来创建一个子网格布局。
  4. 子网格项:在FlexGrid中添加了四个子网格项FlexGridItem,每个子网格项包含一个不同颜色的Container,并在中心显示一个文本。

请注意,FlexGridcolumns属性定义了子网格的列数,而gap属性定义了网格项之间的间距。GridView.buildergridDelegate则定义了主网格的列数和间距。

这个示例展示了如何在Flutter应用中使用flex_grid插件来创建嵌套的网格布局。你可以根据需要调整网格项的数量、颜色和布局。

回到顶部