Flutter 中 GridView 内的可拖动元素位置错误

Draggable element inside a GridView in flutter has wrong position

大家好我正在尝试使用图标的 GridView,我想将这些元素拖到另一个小部件中的 GridView 之外。一旦我开始拖动图标,开始拖动点和反馈小部件之间就会有间隙。我也试过设置 feedbackOffset 但没用。

我准备了一个示例代码作为POC

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.blue,
      ),
      home: IconsCollector(),
    );
  }
}

// import 'package:flutter_svg_provider/flutter_svg_provider.dart';

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

  @override
  _IconsCollectorState createState() => _IconsCollectorState();
}

class _IconsCollectorState extends State<IconsCollector> {
  List<Widget> out = [];

  List iconlist = [
    Icon(Icons.ac_unit),
    Icon(Icons.ac_unit),
    Icon(Icons.ac_unit),
    Icon(Icons.ac_unit),
    Icon(Icons.ac_unit),
  ];

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    var screensize = MediaQuery.of(context).size;

    return 
    GridView.builder(
                scrollDirection: Axis.vertical,
                itemCount: iconlist.length,
                gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 7,
                ),
                itemBuilder: (BuildContext context, int index) {
                  return Draggable(
                      hitTestBehavior: HitTestBehavior.translucent,
                      feedback:  Container(
                          width: screensize.width * 0.1,
                          height: screensize.height * 0.55,
                          margin: EdgeInsets.all(12),
                          decoration: new BoxDecoration(
                            boxShadow: <BoxShadow>[
                              BoxShadow(
                                color: Colors.grey,
                                offset: Offset(1.1, 1.1),
                                blurRadius: 10.0,
                              ),
                            ],
                            color: Colors.white,
                            border: Border.all(width: 5),
                            // borderRadius: new BorderRadius.all(Radius.circular(30.0)),
                            shape: BoxShape.circle,
                          ),

                          child: ClipRRect(
                              borderRadius: BorderRadius.circular(30.0),
                              child: iconlist[index])),
                      data: index,
                      child: Container(
                          width: screensize.width * 0.1,
                          height: screensize.height * 0.55,
                          margin: EdgeInsets.all(12),
                          decoration: new BoxDecoration(
                            boxShadow: <BoxShadow>[
                              BoxShadow(
                                color: Colors.grey,
                                offset: Offset(1.1, 1.1),
                                blurRadius: 10.0,
                              ),
                            ],
                            color: Colors.white,
                            border: Border.all(width: 5),
                            // borderRadius: new BorderRadius.all(Radius.circular(30.0)),
                            shape: BoxShape.circle,
                          ),

                          child: ClipRRect(
                              borderRadius: BorderRadius.circular(30.0),
                              child: iconlist[index])));
                });
          

    
  }
}

有人知道如何解决这个问题吗?我不能使用 drag_and_drop_gridview 因为我想将图标拖到 GridView 之外。

我的 flutter doctor 输出:

[✓] Flutter (Channel stable, 2.2.3, on Linux, locale en_US.utf8)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[✓] Chrome - develop for the web
[✓] Linux toolchain - develop for Linux desktop
[✓] Android Studio (version 4.1)
[✓] VS Code (version 1.58.2)
[✓] Connected device (3 available)

• No issues found!

我附上模拟器的截图。同样的事情也发生在真实设备上。 Note the gap between the mouse pointer and the dragged icon 谢谢大家的建议!

发生这种情况是因为在反馈中您的容器尺寸很大,并且您在这里使用透明背景剪裁我修复了它,

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: IconsCollector(),
    );
  }
}

// import 'package:flutter_svg_provider/flutter_svg_provider.dart';

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

  @override
  _IconsCollectorState createState() => _IconsCollectorState();
}

class _IconsCollectorState extends State<IconsCollector> {
  List<Widget> out = [];

  List iconlist = [
    Icon(Icons.ac_unit),
    Icon(Icons.ac_unit),
    Icon(Icons.ac_unit),
    Icon(Icons.ac_unit),
    Icon(Icons.ac_unit),
  ];

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    var screensize = MediaQuery.of(context).size;

    return GridView.builder(
        scrollDirection: Axis.vertical,
        itemCount: iconlist.length,
        gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 7,
        ),
        itemBuilder: (BuildContext context, int index) {
          return Draggable(
            hitTestBehavior: HitTestBehavior.translucent,
            feedback: Container(
              height:120,
              width:120,
              decoration: new BoxDecoration(
                boxShadow: <BoxShadow>[
                  BoxShadow(
                    color: Colors.grey,
                    offset: Offset(1.1, 1.1),
                    blurRadius: 10.0,
                  ),
                ],
                color: Colors.white,
                border: Border.all(width: 5),
                shape: BoxShape.circle,
              ),
              child: ClipRRect(
                borderRadius: BorderRadius.circular(30.0),
                child: iconlist[index],
              ),
            ),
            data: index,
            child: Container(
              width: screensize.width * 0.1,
              height: screensize.height * 0.55,
              margin: EdgeInsets.all(12),
              decoration: new BoxDecoration(
                boxShadow: <BoxShadow>[
                  BoxShadow(
                    color: Colors.grey,
                    offset: Offset(1.1, 1.1),
                    blurRadius: 10.0,
                  ),
                ],
                color: Colors.white,
                border: Border.all(width: 5),
                shape: BoxShape.circle,
              ),
              child: ClipRRect(
                borderRadius: BorderRadius.circular(30.0),
                child: iconlist[index],
              ),
            ),
          );
        });
  }
}