Flutter拖拽网格布局插件drag_grid的使用

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

Flutter拖拽网格布局插件drag_grid的使用

1. 安装插件

首先,你需要在 pubspec.yaml 文件中添加 drag_grid 插件,并运行命令行安装。

dependencies:
  drag_grid: ^1.0.8

然后,在命令行中执行以下命令:

flutter pub get

2. 示例代码

下面是一个完整的示例代码,展示了如何使用 drag_grid 插件创建一个支持拖拽功能的网格布局。

import 'package:flutter/material.dart';
import 'package:drag_grid/drag_grid.dart';
import 'package:drag_grid/drag_grid_controller.dart';
import 'package:flutter_vibrate/flutter_vibrate.dart';

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

class TestData {
  TestData({
    this.value = '0',
    this.color,
  });

  String value;
  Color? color;
}

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

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

class _MyAppState extends State<MyApp> {
  GridController<TestData> gridController = GridController();
  List<TestData> itemList = [];
  int lastIndex = 0;

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

    itemList = List.generate(16, (i) =&gt; TestData(value: '$i'));
    lastIndex = 16;
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    const sliverGridDelegate = SliverGridDelegateWithFixedCrossAxisCount(
      crossAxisCount: 4,
      mainAxisSpacing: 10,
      crossAxisSpacing: 10,
      childAspectRatio: 1,
    );

    return Stack(
      fit: StackFit.expand,
      children: [
        ListView(
          shrinkWrap: false,
          padding: const EdgeInsets.only(
            top: 20.0,
            left: 20.0,
            right: 19.0,
            bottom: 24.0,
          ),
          children: [
            SizedBox(
              child: DragGrid&lt;TestData&gt;(
                itemList: itemList,
                gridController: gridController,
                sliverGridDelegate: sliverGridDelegate,
                itemBuilder: (context, item, index) {
                  return Container(
                    alignment: Alignment.center,
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: [
                        Container(
                          width: 64.0,
                          height: 64.0,
                          decoration: ShapeDecoration(
                            gradient: const RadialGradient(
                              center: Alignment(0.0, 0.0),
                              radius: 1.5,
                              colors: [
                                Color(0xffe0e0e0),
                                Color(0xfff0f0f0),
                              ],
                            ),
                            shape: RoundedRectangleBorder(
                              borderRadius: BorderRadius.circular(
                                5.0,
                              ),
                            ),
                          ),
                          child: Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            crossAxisAlignment: CrossAxisAlignment.center,
                            children: [
                              Text(
                                item.value,
                                style: const TextStyle(
                                  color: Color(0xff404244),
                                  fontWeight: FontWeight.bold,
                                  fontSize: 16.0,
                                  height: 1,
                                ),
                              ),
                            ],
                          ),
                        ),
                      ],
                    ),
                  );
                },
                itemListChanger: (list) {
                  setState(() {
                    itemList = list;
                  });
                },
                onDragStarted: () async {
                  if (await Vibrate.canVibrate) {
                    Vibrate.feedback(FeedbackType.heavy);
                  }
                },
              ),
            ),
          ],
        ),
        Positioned(
          left: 0,
          bottom: 48,
          child: Container(
            width: MediaQuery.of(context).size.width,
            padding: const EdgeInsets.symmetric(horizontal: 48.0),
            child: Column(
              children: [
                GestureDetector(
                  behavior: HitTestBehavior.opaque,
                  child: Container(
                    height: 52.0,
                    margin: const EdgeInsets.symmetric(vertical: 10.0),
                    alignment: Alignment.center,
                    decoration: ShapeDecoration(
                      gradient: const RadialGradient(
                        center: Alignment(0.0, 0.0),
                        radius: 1.8,
                        colors: [
                          Color(0xffe0e0e0),
                          Color(0xfff0f0f0),
                        ],
                      ),
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(
                          12.0,
                        ),
                      ),
                    ),
                    child: const Text(
                      '在第2个元素插入',
                      style: TextStyle(
                        fontSize: 14.0,
                        fontWeight: FontWeight.bold,
                        color: Color(0xff707377),
                        letterSpacing: 1.5,
                        height: 1,
                      ),
                    ),
                  ),
                  onTap: () {
                    gridController.insert(
                      item: TestData(value: '${lastIndex++}'),
                      index: 1,
                    );
                  },
                ),
                GestureDetector(
                  behavior: HitTestBehavior.opaque,
                  child: Container(
                    height: 52.0,
                    margin: const EdgeInsets.symmetric(vertical: 10.0),
                    alignment: Alignment.center,
                    decoration: ShapeDecoration(
                      gradient: const RadialGradient(
                        center: Alignment(0.0, 0.0),
                        radius: 1.8,
                        colors: [
                          Color(0xffe0e0e0),
                          Color(0xfff0f0f0),
                        ],
                      ),
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(
                          12.0,
                        ),
                      ),
                    ),
                    child: const Text(
                      '删除第2个元素',
                      style: TextStyle(
                        fontSize: 14.0,
                        fontWeight: FontWeight.bold,
                        color: Color(0xff707377),
                        letterSpacing: 1.5,
                        height: 1,
                      ),
                    ),
                  ),
                  onTap: () {
                    gridController.remove(index: 1);
                  },
                ),
              ],
            ),
          ),
        )
      ],
    );
  }
}

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

1 回复

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


当然,以下是一个关于如何在Flutter中使用drag_grid插件来实现拖拽网格布局的示例代码。drag_grid插件允许你创建一个可以拖拽排序的网格视图。

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

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

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

接下来,你可以使用以下代码来创建一个简单的拖拽网格布局:

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

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

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

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final List<String> items = List.generate(25, (i) => "Item ${i + 1}");

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Drag Grid Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: DragGrid<String>(
          data: items,
          itemBuilder: (context, item, index) {
            return Card(
              child: Center(
                child: Text(item),
              ),
            );
          },
          onReorder: (oldIndex, newIndex) {
            if (oldIndex < newIndex) {
              newIndex -= 1;
            }
            final String item = items.removeAt(oldIndex);
            items.insert(newIndex, item);
            setState(() {});
          },
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 3,
            crossAxisSpacing: 4.0,
            mainAxisSpacing: 4.0,
            childAspectRatio: 1.0,
          ),
        ),
      ),
    );
  }
}

代码解释

  1. 依赖引入

    • pubspec.yaml中添加drag_grid依赖。
  2. 主应用

    • MyApp是一个无状态组件,定义了应用的主题和主页。
  3. 主页

    • MyHomePage是一个有状态组件,包含了一个List<String>来存储网格项。
    • 使用DragGrid组件来显示网格布局,并允许用户拖拽排序。
  4. DragGrid组件

    • data:传入要显示的网格项数据。
    • itemBuilder:定义了每个网格项的构建方式,这里使用了CardText
    • onReorder:当用户拖拽网格项后,这个回调会被触发,用于更新数据顺序。
    • gridDelegate:定义了网格的布局,这里使用SliverGridDelegateWithFixedCrossAxisCount来创建一个固定列数的网格布局。

这段代码展示了如何使用drag_grid插件来创建一个简单的拖拽网格布局,你可以根据需要进一步自定义和扩展这个示例。

回到顶部