Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Popup menu in reorderable list is out of position

Tags:

flutter

dart

Does anyone know why the PopupMenuButton renders at the wrong place when used in a ReorderableListView? It seems to render correctly when used inside a normal ListView.

Here is an example screenshot:

Example of problem

For those that want example code:

import 'package:flutter/material.dart';

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

class ListApp extends StatefulWidget {
  @override
  _ListAppState createState() => _ListAppState();
}

class _ListAppState extends State<ListApp> {
  List<String> items = [
    "Item 1",
    "Item 2",
    "Item 3",
    "Item 4",
    "Item 5",
    "Item 6",
    "Item 7",
  ];
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Reorder List'),
        ),
        body: Container(
          child: ReorderableListView(
              // child: ListView(

              onReorder: (oldIndex, newIndex) {
                int deleteIndex = oldIndex;
                items.insert(newIndex, items[oldIndex]);

                if (oldIndex > newIndex) {
                  // The old index is now 1 index higher
                  deleteIndex++;
                }
                items.removeAt(deleteIndex);
                setState(() {
                  items = items;
                });
              },

              children: items.map((item) {
                return Card(
                  key: Key(item),
                  child: ListTile(
                    title: Text(item),
                    trailing: PopupMenuButton(
                      itemBuilder: (context) {
                        return [
                          PopupMenuItem(
                            child: Text(item),
                            value: item,
                          )
                        ];
                      },
                    ),
                  ),
                );
              }).toList()),
        ),
      ),
    );
  }
}

Could it be that I'm using the PopupMenuButton the wrong way or is this Widget buggy?

I'd like my list to be sortable but the PopupMenuButton appearing at the wrong place is a problem.

like image 800
Touch Avatar asked Mar 03 '23 15:03

Touch


2 Answers

It seems that the problem should be in the ReorderableListView widget's code, but in fact it's hidden in PopupMenu. To calculate popup position this code evaluates overlay's rendering box:

final RenderBox overlay = Overlay.of(context).context.findRenderObject() as RenderBox;

Because, by default, the Overlay.of method searches hierarchy for the nearest overlay, in case of ReorderableListView it returns internal overlay (one created to restrict dragging gesture) but for ListView it returns root overlay. Since the root navigator used to show popup menu, a shift appears in the former case.

Calling Overlay.of method with rootOverlay: true fixes the bug:

final RenderBox overlay = Overlay.of(context, rootOverlay: true).context.findRenderObject() as RenderBox;

Patching Flutter SDK is the most appropriate solution.

like image 95
Spatz Avatar answered Mar 05 '23 18:03

Spatz


I think this is as best as you can get it without tapping into the widget

enter image description here

             PopupMenuButton(
                  offset: Offset(0, 50), //add offset to fix it
                  itemBuilder: (context) {
                    return [
                      PopupMenuItem(
                        child: Text(item),
                        value: item,
                      )
like image 37
LonelyWolf Avatar answered Mar 05 '23 18:03

LonelyWolf