skip to Main Content

Going with the mouse hover one tile of my ReordableListView.
I should see the edit and delete icons, together with a change of color. What I have is that selecting one tile, I see the behavior on all the tiles instead of just the one selected.


Here is a snippet of my code.

ReorderableListView(
      padding: const EdgeInsets.symmetric(horizontal: 40),
      buildDefaultDragHandles: false,
      children: <Widget>[
        for (int index = 0; index < widget.fieldsList.length; index += 1)
          ListTile(
            key: Key('$index'),
            leading: SizedBox(
              width: 50,
              child: ReorderableDragStartListener(
                index: index,
                child: const Icon(Icons.drag_handle)
              ),
            ),
            title: MouseRegion(
              onEnter: (details) => setState(() => isHover = true),
              onExit: (details) => setState(() => isHover = false),
              onHover: (details) => setState(() => isHover = true),
              child: Stack(
                children: [
                  Container(
                      color: isHover
                          ? Colors.grey.shade100
                          : Colors.transparent,
                      child:
                          showComponent(componentList[index].type)),
                  Positioned(
                      top: 0,
                      right: 0,
                      child: isHover
                          ? Row(
                              children: [
                                Container(
                                  child: IconButton(
                                      icon: Icon(Icons.edit), onPressed: () {}),
                                ),
                                Container(
                                  child: IconButton(
                                      icon: Icon(Icons.delete),
                                      onPressed: () {}),
                                ),
                              ],
                            )
                          : Container()),
                ],
              ),
            ),
          ),
      ],
      onReorder: (int oldIndex, int newIndex) {
        setState(() {
          final item = componentList[oldIndex];
          componentList[oldIndex] = componentList[newIndex];
          componentList[newIndex] = item;
        });
      },
    );

The behaviour is correct, but I want that it’s shown on only one tile at time.

2

Answers


  1. All of ListTiles are using/sharing the same isHover boolean variable. To solve this, you should store the hover index instead of hover state (boolean), then you will test if index==hover index in the loop.

    int? hoverIndex;
    onEnter: (details) => setState(() => hoverIndex = index),
              onExit: (details) => setState(() => hoverIndex = null),
              onHover: (details) => setState(() => hoverIndex = index),
    child: Stack(
                children: [
                  Container(
                      color: index == hoverIndex
                          ? Colors.grey.shade100
                          : Colors.transparent,
    

    Hope this helps.

    Login or Signup to reply.
  2. Instead of using bool use nullable int to track the hover index.

      int? hoverItemIndex;
    

    And perform the condition like

     MouseRegion(
      onEnter: (details) =>
          setState(() => hoverItemIndex = index),
      onExit: (details) =>
          setState(() => hoverItemIndex = null),
      onHover: (details) =>
          setState(() => hoverItemIndex = index),
    

    Chaning ui will be

     hoverItemIndex == index ? Row(...) :
    

    or just use if(hoverItemIndex == index) Row(...)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search