flutter 显示菜单位置抖动

bhmjp9jg  于 2023-01-31  发布在  Flutter
关注(0)|答案(3)|浏览(91)

我有一个GridView小部件,其中包含一些 Package 有GestureDetector的GridTile,尝试显示一个菜单以删除GridTile(当我长按时),,,一切正常,只是我希望菜单从我单击的位置显示,而不是显示在应用程序的顶部

showMenu(
            context: context,
            position: ..........,// Here i want the solution
            items: [
              PopupMenuItem(
                child: FlatButton.icon(
                  onPressed: () {
                    _notesProv.deleteNote(id);
                    Navigator.of(context).pop();
                  },
                  icon: Icon(
                    Icons.delete,
                    color: Colors.black,
                  ),
                  label: Text(
                    'delete note',
                    style: TextStyle(color: Colors.black),
                  ),
                ),
              ),
            ],
            color: Colors.green[100],
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(30),
            ));
tuwxkamq

tuwxkamq1#

请参阅代码中的注解,以获得关于所发生的事情的指导。
只要有注解,代码就会添加到示例Gridview stolen from Flutter official cookbook中,以便在您点击的位置弹出菜单。

class GridPositionPage extends StatefulWidget {
  @override
  _GridPositionPageState createState() => _GridPositionPageState();
}

class _GridPositionPageState extends State<GridPositionPage> {

  // ↓ hold tap position, set during onTapDown, using getPosition() method
  Offset tapXY;
  // ↓ hold screen size, using first line in build() method
  RenderBox overlay;

  @override
  Widget build(BuildContext context) {
    // ↓ save screen size
    overlay = Overlay.of(context).context.findRenderObject();

    return BaseExamplePage(
      title: 'Grid Position',
      child: GridView.count(
        crossAxisCount: 2,
        children: List.generate(100, (index) {
          return Center(
            child: InkWell(
              child: Text(
                'Item $index',
                style: Theme.of(context).textTheme.headline5,
              ),
              // ↓ save screen tap position now
              onTapDown: getPosition,
              onLongPress: () => showMenu(
                  context: context,
                  position: relRectSize,
                  items: [
                    PopupMenuItem(
                      child: FlatButton.icon(
                        label: Text('Delete'),
                        icon: Icon(Icons.delete),
                      ),
                    )
                  ]
              ),
            ),
          );
        }),
      ),
    );
  }

  // ↓ create the RelativeRect from size of screen and where you tapped
  RelativeRect get relRectSize => RelativeRect.fromSize(tapXY & const Size(40,40), overlay.size);

  // ↓ get the tap position Offset
  void getPosition(TapDownDetails detail) {
    tapXY = detail.globalPosition;
  }
}
x6yk4ghg

x6yk4ghg2#

此函数处理所有内容,您只需使用findRenderObject方法获取每个网格项目上的RenderObject:

void showGridMenu() async {
      Rect? rect;
      RenderBox? overlay = Overlay.of(context).context.findRenderObject() as RenderBox;
      final renderObject = context.findRenderObject();
      final translation = renderObject?.getTransformTo(null).getTranslation();
      if (translation != null && renderObject?.paintBounds != null) {
      final offset = Offset(translation.x, translation.y);
      rect = renderObject!.paintBounds.shift(offset);
      }
      if (rect != null) {
      var value = await showMenu<String>(
      context: context,
      position: RelativeRect.fromRect(
        rect,
        Offset.zero & overlay.size,
      ),
      items: [
        const PopupMenuItem(value: 'yes', child: Text('Yes')),
        const PopupMenuItem(value: 'no', child: Text('No')),
      ],
      );
      if (value != null) {
      debugPrint(value);
      }
      }
    }
vlf7wbxs

vlf7wbxs3#

position: RelativeRect.fromSize(
                        Rect.fromCenter(
                            center: Offset.zero, width: 100, height: 100),
                        Size(100, 100),
                  ),

像这样的事

相关问题