Search code examples
flutterdartuser-interfacelistview

Hovering over menu items on a ListTile highlights the list item that contains it and does not go away


With the following code below, when I click on the menu anchor button and hover my mouse over the menu items, the ListTile underneath it also gets highlighted. After that, toggling the menu off will still leave the ListTile "highlighted" and stays highlighted with no way of disabling it. How do I prevent that from happening?

DartPad Demo

Also, how are you supposed to debug this behavior in VSCode?

ListView.builder(
  itemCount: tasks.length,
  itemBuilder: (context, index) {
    final task = tasks[index];
    return Material(
      key: Key(task.id.toString()),
      type: MaterialType.transparency,
      child: ListTile(
        title: Text(task.name),
        onTap: () async {},
        trailing: MenuAnchor(
          menuChildren: menuItems
              .map(
                (item) => Material(
                  child: MenuItemButton(
                    child: Text(item),
                    onPressed: () {},
                  ),
                ),
              )
              .toList(),
          builder: (context, controller, child) => IconButton(
            icon: const Icon(Icons.more_vert),
            onPressed: () {
              if (controller.isOpen) {
                controller.close();
              } else {
                controller.open();
              }
            },
          ),
        ),
      ),
    );
  },
)

Searching on the web and on the flutter repo for a mention of this behavior and I found none. I tried wrapping the MenuItemButton with Material but that didn't seem to help.

Demo of ListView and menu item interaction


Solution

  • Seems like the focus is trapped in the ListTile once the menu item is highlighted. To debug this behavior, observe the focus change on each ListTile with the onFocusChange callback:

    ListTile(
      onFocusChange: (hasFocus) {
        // ...
      },
    )
    

    I can think of three approaches to fix this.

    1. Manage the focus node of the ListTiles manually so you can unfocus them
    2. Use MenuBar instead of MenuAnchor
    3. Set the focus color of the ListTile to transparent

    For the last approach, you would do

    ListTile(
      focusColor: Colors.transparent,
      // ...
    )