首页 > 解决方案 > Flutter web - ReordorableListView,在字段之间悬停时带有+按钮

问题描述

我正在做一个 Flutter Web 项目,我们想要一个ReordorableListView设计。当用户悬停在 2 个元素之间时,我们还希望在列表的卡片之间有一个“+”按钮(然后在所选位置添加一个元素)。

我试图通过在列表中包含一个小部件(它是透明的并且在悬停时变成“+” )来做到这一点。但是通过这样做,这个小部件也可以由我不想要的用户拖动。

这是一个简单的例子:

class Screen extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return ReorderableListView(
      onReorder: (int oldIndex, int newIndex) {},
      children: [
        const Card(
          child: Padding(
            padding: EdgeInsets.all(8.0),
            child: Text('Value 0'),
          ),
          key: Key('key0'),
        ),
        PlusButton(
          key: Key('plusButton'),
        ),
        const Card(
          child: Padding(
            padding: EdgeInsets.all(8.0),
            child: Text('Value 1'),
          ),
          key: Key('key1'),
        ),
        const Card(
          child: Padding(
            padding: EdgeInsets.all(8.0),
            child: Text('Value 2'),
          ),
          key: Key('key2'),
        ),
      ],
    );
  }
}

class PlusButton extends StatefulWidget {
  PlusButton({Key key}) : super(key: key);
  @override
  _PlusButtonState createState() => _PlusButtonState();
}

class _PlusButtonState extends State<PlusButton> {
  bool isHovered = false;
  @override
  Widget build(BuildContext context) {
    return MouseRegion(
      onEnter: (_) {
        print('enter');
        setState(() {
          isHovered = true;
        });
      },
      onExit: (_) {
        print('exit');
        setState(() {
          isHovered = false;
        });
      },
      child: Container(
        height: 20,
        width: 50,
        color: Colors.red, // Should be transparent, red to see it in the example
        child: isHovered
            ? IconButton(
                iconSize: 10,
                icon: const Icon(Icons.add),
                onPressed: () {},
              )
            : null,
      ),
    );
  }
}

名单 :

在此处输入图像描述

当按钮悬停时:

在此处输入图像描述

如您所见,按钮也是可拖动的:

在此处输入图像描述

当用户悬停在那里时,如何在 2 个元素之间显示“+”按钮?

标签: flutterlistviewdartdrag-and-drophover

解决方案


我没有找到任何合适的方法来做我想做的事。我发现的一种解决方法是在按钮上放置GestureDetector一个Container非空(但为空)的按钮,onLongPress以阻止小部件的拖动。

这是更新的代码:

class Screen extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return ReorderableListView(
      onReorder: (int oldIndex, int newIndex) {},
      children: [
        const Card(
          child: Padding(
            padding: EdgeInsets.all(8.0),
            child: Text('Value 0'),
          ),
          key: Key('key0'),
        ),
        PlusButton(
          key: Key('plusButton'),
        ),
        const Card(
          child: Padding(
            padding: EdgeInsets.all(8.0),
            child: Text('Value 1'),
          ),
          key: Key('key1'),
        ),
        const Card(
          child: Padding(
            padding: EdgeInsets.all(8.0),
            child: Text('Value 2'),
          ),
          key: Key('key2'),
        ),
      ],
    );
  }
}

class PlusButton extends StatefulWidget {
  PlusButton({Key key}) : super(key: key);
  @override
  _PlusButtonState createState() => _PlusButtonState();
}

class _PlusButtonState extends State<PlusButton> {
  bool isHovered = false;
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onLongPress: () {}, // To prevent the drag
      child: MouseRegion(
        onEnter: (_) {
          print('enter');
          setState(() {
            isHovered = true;
          });
        },
        onExit: (_) {
          print('exit');
          setState(() {
            isHovered = false;
          });
        },
        child: Container(
          height: 20,
          width: 50,
          color: Colors.red, // Should be transparent, red to see it in the example
          child: isHovered
              ? IconButton(
                  iconSize: 10,
                  icon: const Icon(Icons.add),
                  onPressed: () {},
                )
              : null,
        ),
      ),
    );
  }
}

推荐阅读