Flutter动态网格布局插件dynamic_grid_view的使用

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

Flutter动态网格布局插件dynamic_grid_view的使用

特性

如何在SingleChildScrollView中使用GridView?

有时我们需要在SingleChildScrollView中使用GridView,例如在开发电商应用时。现在的问题是,你不能直接在SingleChildScrollView中创建GridView,因为两者都会试图占用尽可能多的空间,这会导致高度不受限制/无限。

DynamicGridView提供了这个问题的解决方案。

开始使用

TODO:列出前提条件并提供或指向如何开始使用该包的信息。

使用方法

DynamicGridView(
  width: width,
  horizontalPadding: 16,
  dataSet: items,
  child: (context, index) {return yourGridElement},
),
  • count 是项目总数或itemCount。
  • itemsPerRow 是每行项目的数量或crossAxisCount。
  • ratio 是GridView的childAspectRatio属性,通常用于设置网格内项目的大小。ratio计算为宽度/高度。
  • horizontalPadding 是给GridView的水平填充(在垂直列表的情况下)。
  • child 是从GridView返回的元素。

示例代码

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

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

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

  // 这个小部件是您的应用程序的根。
  [@override](/user/override)
  Widget build(BuildContext context) {
    return const MaterialApp(title: '动态GridView', home: Home());
  }
}

class Home extends StatelessWidget {
  const Home({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    final double width = MediaQuery.of(context).size.width;
    final double height = MediaQuery.of(context).size.height;
    return Scaffold(
      body: SingleChildScrollView(
        child: Column(
          children: [
            DynamicGridView(
              width: width,
              horizontalPadding: 16,
              dataSet: List.filled(16, 0), // 创建一个包含16个0的列表
              child: (context, index) {
                return SizedBox(
                  child: Card(
                    clipBehavior: Clip.hardEdge,
                    child: Column(
                      children: [
                        Expanded(
                            child: Image.network(
                                "https://picsum.photos/200?${DateTime.now().millisecondsSinceEpoch.toString()}")), // 获取随机图片
                        const Padding(
                          padding: EdgeInsets.symmetric(horizontal: 4.0),
                          child: Text(
                            "Lorem Ipsum是虚拟文本,lorem ipsum",
                            maxLines: 3,
                            overflow: TextOverflow.ellipsis,
                            style: TextStyle(
                                fontSize: 10, fontWeight: FontWeight.bold),
                            textAlign: TextAlign.start,
                          ),
                        ),
                      ],
                    ),
                  ),
                );
              },
            ),
          ],
        ),
      ),
    );
  }
}

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

1 回复

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


当然,以下是一个关于如何使用 dynamic_grid_view 插件来实现 Flutter 动态网格布局的示例代码。dynamic_grid_view 插件允许你根据屏幕尺寸和内容动态调整网格布局。

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

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

然后,运行 flutter pub get 来获取依赖。

接下来,你可以在你的 Flutter 应用中使用 DynamicGridView 来创建动态网格布局。以下是一个完整的示例代码:

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

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

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

class MyHomePage extends StatelessWidget {
  final List<String> items = List.generate(50, (index) => "Item $index");

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Dynamic GridView Demo'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: DynamicGridView<String>(
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 2, // 初始列数
            crossAxisSpacing: 4.0,
            mainAxisSpacing: 4.0,
          ),
          itemCount: items.length,
          itemBuilder: (BuildContext context, int index) {
            return Card(
              color: Colors.primary.withOpacity(0.1),
              child: Center(
                child: Text(items[index]),
              ),
            );
          },
          // 监听屏幕尺寸变化以动态调整列数
          onLayoutChanged: (BoxConstraints constraints) {
            final screenWidth = constraints.maxWidth;
            int crossAxisCount;
            if (screenWidth < 400) {
              crossAxisCount = 1;
            } else if (screenWidth < 800) {
              crossAxisCount = 2;
            } else {
              crossAxisCount = 3;
            }
            // 更新 gridDelegate 的 crossAxisCount
            setState(() {
              // 假设你在一个StatefulWidget中,这里你需要某种方式来更新gridDelegate
              // 在这个示例中,我们假设你有一个变量来存储gridDelegate
              // 并在这里更新它,但在实际使用中,你可能需要更复杂的逻辑来处理这个更新
              // 这里只是演示逻辑,所以直接返回一个新的gridDelegate,但在真实场景中你需要管理状态
              // 注意:这个setState调用在实际代码中可能不适用,因为我们在一个StatelessWidget中
              // 你需要在你的StatefulWidget中实现这个逻辑
            });
            // 注意:上面的setState调用仅用于说明目的,实际使用时需要在StatefulWidget中管理状态
            // 返回新的crossAxisCount值(这里仅演示,实际代码需要根据你的架构来调整)
            return crossAxisCount;
          },
          // 注意:上面的onLayoutChanged方法在实际使用中需要调整,
          // 因为它依赖于setState来更新UI,而这在StatelessWidget中是不可能的。
          // 你应该在一个StatefulWidget中管理这个状态,并在屏幕尺寸变化时调用setState。
          // 下面的示例将展示如何在StatefulWidget中实现这一点。
        ),
      ),
    );
  }
}

// 由于上面的代码示例在StatelessWidget中调用了setState,这是不正确的,
// 下面是一个修正后的版本,它在StatefulWidget中管理状态。
class CorrectDynamicGridView extends StatefulWidget {
  @override
  _CorrectDynamicGridViewState createState() => _CorrectDynamicGridViewState();
}

class _CorrectDynamicGridViewState extends State<CorrectDynamicGridView> {
  int _crossAxisCount = 2;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Correct Dynamic GridView Demo'),
      ),
      body: LayoutBuilder(
        builder: (BuildContext context, BoxConstraints constraints) {
          final screenWidth = constraints.maxWidth;
          int newCrossAxisCount;
          if (screenWidth < 400) {
            newCrossAxisCount = 1;
          } else if (screenWidth < 800) {
            newCrossAxisCount = 2;
          } else {
            newCrossAxisCount = 3;
          }
          if (newCrossAxisCount != _crossAxisCount) {
            setState(() {
              _crossAxisCount = newCrossAxisCount;
            });
          }
          return Padding(
            padding: const EdgeInsets.all(8.0),
            child: DynamicGridView<String>(
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: _crossAxisCount,
                crossAxisSpacing: 4.0,
                mainAxisSpacing: 4.0,
              ),
              itemCount: MyHomePage().items.length,
              itemBuilder: (BuildContext context, int index) {
                return Card(
                  color: Colors.primary.withOpacity(0.1),
                  child: Center(
                    child: Text(MyHomePage().items[index]),
                  ),
                );
              },
            ),
          );
        },
      ),
    );
  }
}

注意

  1. 上面的 MyHomePage 类中的 onLayoutChanged 方法示例仅用于说明目的,并不能直接工作,因为 setState 不能在 StatelessWidget 中调用。
  2. CorrectDynamicGridView 类提供了一个修正后的版本,它在 StatefulWidget 中管理状态,并使用 LayoutBuilder 来监听屏幕尺寸变化。

请根据你的具体需求调整上面的代码。希望这个示例能帮助你理解如何在 Flutter 中使用 dynamic_grid_view 插件实现动态网格布局。

回到顶部