Как я могу получить позицию щелчка PopupMenuItem на главной странице во Flutter

Я создаю функцию showPopupMenu , потому что мне нужно это несколько раз в этом проекте. Когда я щелкну элемент в showPopupMenu , в этот раз мне нужна позиция щелчка на главной странице. Как я могу это сделать?

Вот код моей главной страницы:

       return MaterialApp(
  home: Scaffold(
      appBar: const CustomToolbar(title: 'Test Screen'),
      body: Column(
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              const Padding(
                padding: EdgeInsets.only(left: 10),
                child: Text('Notice Board',
                    style: TextStyle(
                        fontFamily: 'Montserrat Bold',
                        color: Colors.black)),
              ),
              InkWell(
                  onTapDown: (TapDownDetails tap) {
                    var menus = <String>['Edit', 'Delete'];
                    showPopupMenu(context, tap, menus);
                    //I want to clicked position here
                  },
                  child: const Icon(Icons.more_vert, color: Colors.grey))
            ],
          )
        ],
      )),
);

А вот мой код метода showPopupMenu :

      void showPopupMenu(
BuildContext context, TapDownDetails tap, List<String> menus) async { await showMenu(
context: context,
position: RelativeRect.fromLTRB(
    tap.globalPosition.dx, tap.globalPosition.dy, 0, 0),
items: [
  if (menus.isNotEmpty)
    PopupMenuItem<String>(
        value: menus[0], onTap: () {}, child: Text(menus[0])),
  if (menus.length > 1)
    PopupMenuItem<String>(value: menus[1], child: Text(menus[1])),
  if (menus.length > 2)
    PopupMenuItem<String>(value: menus[2], child: Text(menus[2])),
  if (menus.length > 3)
    PopupMenuItem<String>(value: menus[3], child: Text(menus[3]))
],
elevation: 8.0);}

2 ответа

Попробуй это:

          GestureDetector(
          onTapDown: (TapDownDetails tap) {
            var menus = <String>['Edit', 'Delete'];
              var clickPos = await showPopupMenu(context, tap, menus);
              if (clickPos != null) {
                print("Click at $clickPos");
              }
          },
          child: const Icon(Icons.more_vert, color: Colors.grey),
        )


 Future showPopupMenu(BuildContext context, TapDownDetails tap, List<String> menus, {double buttonHeight = 24, double buttonWidth = 24}) async {
    var dx = tap.globalPosition.dx - (tap.localPosition.dx - buttonWidth);
    var dy = tap.globalPosition.dy - (tap.localPosition.dy - buttonHeight);
    return showMenu(
        context: context,
        position: RelativeRect.fromLTRB(dx, dy, dx, dy),
        items: menus.map((e) => PopupMenuItem<String>(value: e, onTap: () {}, child: Text(e))).toList(),
        elevation: 8.0);
  }

Это код виджета главной страницы

       InkWell(
                onTapDown: (TapDownDetails tap) async {
                  var menus = <String>['Edit', 'Delete'];
                  String clickPos =
                      await showPopupMenus(context, tap, menus);
                  setState(() {
                    print("Click on $clickPos");
                  });
                },
                child: const Icon(Icons.more_vert, color: Colors.grey),
              )

а вот постоянный код

      Future<String> showPopupMenus(
    BuildContext context, TapDownDetails tap, List<String> menus) async {
  String _value = "";
  await showMenu(
    context: context,
    position: RelativeRect.fromLTRB(
        tap.globalPosition.dx, tap.globalPosition.dy, 0, 0),
    items: [
      if (menus.isNotEmpty)
        PopupMenuItem<String>(
            value: menus[0], onTap: () {}, child: Text(menus[0])),
      if (menus.length > 1)
        PopupMenuItem<String>(value: menus[1], child: Text(menus[1])),
      if (menus.length > 2)
        PopupMenuItem<String>(value: menus[2], child: Text(menus[2])),
      if (menus.length > 3)
        PopupMenuItem<String>(value: menus[3], child: Text(menus[3]))
    ],
    elevation: 8.0,
  ).then((value) {
    if (value != null) {
      // print("Position $value");
      _value = value;
    }
  });
  return _value;
}

Здесь я возвращаю String. Если вы хотите вернуть позицию (int), используйте код ниже.
Этот код для виджета

      InkWell(
                onTapDown: (TapDownDetails tap) async {
                  var menus = <String>['Edit', 'Delete'];
                  int clickPos =
                      await showPopupMenus(context, tap, menus);
                  setState(() {
                    print("Click on $clickPos");
                  });
                },
                child: const Icon(Icons.more_vert, color: Colors.grey),
              )

И этот код для константы

      Future<int> showPopupMenus(
    BuildContext context, TapDownDetails tap, List<String> menus) async {
  int _value = -1;
  await showMenu(
    context: context,
    position: RelativeRect.fromLTRB(
        tap.globalPosition.dx, tap.globalPosition.dy, 0, 0),
    items: [
      if (menus.isNotEmpty)
        PopupMenuItem<int>(
            value: 0, onTap: () {}, child: Text(menus[0])),
      if (menus.length > 1)
        PopupMenuItem<int>(value: 1, child: Text(menus[1])),
      if (menus.length > 2)
        PopupMenuItem<int>(value: 2, child: Text(menus[2])),
      if (menus.length > 3)
        PopupMenuItem<int>(value: 3, child: Text(menus[3]))
    ],
    elevation: 8.0,
  ).then((value) {
    if (value != null) {
      // print("Position $value");
      _value = value;
    }
  });
  return _value;
}

Я надеюсь, что это поможет вам. Спасибо

Другие вопросы по тегам