Welcome to MLink Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

dart - Flutter showMenu() x axis position

I have a Gridview builder that generates the following and I have a GestureDetector with onLongPress that shows the menu as such:

cards

I am able to align the menu to respective element of the gridview, for example if I long press on the green box it should show the menu below the box:

enter image description here

However, I am unable to set the horizontal x position.

If I set the value of the L or R, it moves the menu to most left or right, which is not what I want. I want to center the menu to the middle of the x axis of the the green box.

onLongPress: () {
        RenderBox box = key.currentContext.findRenderObject();
        double h = double.parse(box.size.height.toString());
        Offset position =
            box.localToGlobal(Offset.zero); //this is global position
        double y = position.dy;
        double x = position.dx;
        double w = double.parse(box.size.width.toString());

        print(x);
        showMenu(
            context: context,
            position: new RelativeRect.fromLTRB(x, 0, y + h, 0),
            items: <PopupMenuEntry>[
              PopupMenuItem(
                value: 1,
                child: Row(
                  children: <Widget>[
                    Icon(Icons.delete),
                    Text("Delete"),
                  ],
                ),
              )
            ]);
      },

In short I would like to do something like:

enter image description here

  body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          
          Expanded(
            child: GridView.builder(
              shrinkWrap: false,
              itemCount: data.length,
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                childAspectRatio: 10.0 / 10.0,
                crossAxisCount: 2,
              ),
              itemBuilder: (BuildContext context, int index) {
                GlobalKey _key = GlobalKey();

                return Padding(
                  padding: EdgeInsets.all(10),
                  child: CustomCard(data[index], _key),
                );
              },
            ),
          ),
        ],
      ),
    );

CustomCard

 return GestureDetector(
      onTapDown: _storePosition,
      onLongPress: () {
      
        showMenu(
            context: context,
            position:null,
            items: <PopupMenuEntry>[
              PopupMenuItem(
                value: 1,
                child: Row(
                  children: <Widget>[
                    Icon(Icons.delete),
                    Text("Delete"),
                  ],
                ),
              )
            ]);
      },
      child: Card(
        color: d.color,
        elevation: 5,
        semanticContainer: true,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(10.0),
        ),
        clipBehavior: Clip.antiAlias,
        child: Padding(
          padding: EdgeInsets.symmetric(vertical: 20),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              Text(
                d.title,
                style: TextStyle(fontSize: 20, fontWeight: FontWeight.w500),
              ),
            
             
            ],
          ),
        ),
      ),
    );

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This works for me, I took the width / 2 for both the left and right, and Set the top as y + h + 20 (20 to give it extra space) from top.

                    position: new RelativeRect.fromLTRB(
                        w / 2, y + h + 20, w / 2, 0),

This is the Full Working Code on A Container with some height and width.

            GestureDetector(
              onLongPress: () {
                RenderBox box = key.currentContext.findRenderObject();
                double h = double.parse(box.size.height.toString());
                Offset position = box.localToGlobal(
                    Offset.zero); //this is global position
                double y = position.dy;
                double x = position.dx;
                double w = double.parse(box.size.width.toString());
                showMenu(
                    context: context,
                    position: new RelativeRect.fromLTRB(
                        w / 2, y + h + 20, w / 2, 0),
                    items: <PopupMenuEntry>[
                      PopupMenuItem(
                        value: 1,
                        child: Row(
                          children: <Widget>[
                            Icon(Icons.delete),
                            Text("Delete"),
                          ],
                        ),
                      )
                    ]);
              },
              child: new Container(
                key: key,
                color: Colors.red,
                height: 120,
                width: 300,
                child: Center(child: new Text("Tap Me")),
              ),
            ),

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to MLink Developer Q&A Community for programmer and developer-Open, Learning and Share
...