fluttergesturedetector

When adding a Transform to a GestureDetector the onTap no longer works


I am trying to make a navbar with a circle in the center. This circle needs to be a little higher than the rest. When adding a Transform to this circle to move it up, the onTap of the GestureDetector no longer works for the part that is above the rest of the bar.

I have the following code for the navbar:

return Stack(
  children: [
    PageView(),
    Align(
      child: Container(
        height: 96,
        color: Colors.white,
        child: Row(
          children: [
            ...widget.items.mapIndexed(
              (index, item) => index == centerIndex &&
                      widget.variant == TapbarVariant.centerButton
                  ? TapbarCenterItem()
                  : TapbarItem(), // Another item where the onTap does work
            ),
          ],
        ),
      ),
    ),
  ],
);

And this is the TapbarCenterItem:

return Expanded(
  child: GestureDetector(
    onTap: () {},
    behavior: HitTestBehavior.opaque,
    child: Transform.translate(
      offset: _getOffset(context),
      child: Container(
        width: 62,
        height: 62,
        decoration: BoxDecoration(
          color: Colors.white,
          shape: BoxShape.circle,
        ),
        child: Placeholder(),
      ),
    ),
  ),
);

Solution

  • Turns out the answer was to move the center item outside of the map so it could be a Positioned widget.

    This is the final version of the navbar:

    return Stack(
      alignment: Alignment.bottomCenter,
      children: [
        PageView(
          controller: widget.controller,
          physics: const NeverScrollableScrollPhysics(),
          children: widget.screens,
        ),
        Container(
          height: 96,
          width: double.infinity,
          color: Colors.white,
          child: Row(
            children: [
              ...widget.items.mapIndexed(
                (index, item) => index == centerIndex &&
                        widget.variant == TapbarVariant.centerButton
                    ? SizedBox(width: 62)
                    : TapbarItem(
                        onTap: (index) {},
                     ),
              ),
            ],
          ),
        ),
        if (widget.variant == TapbarVariant.centerButton)
          TapbarCenterItem(
            onTap: (index) {},
          ),
      ],
    );
    

    And the final version of the TapbarCenterItem:

    return Positioned(
      bottom: 96 - (62 / 2), // The navbar size minus the centeritemsize devided by 2 to get the center
      child: GestureDetector(
        onTap: () {},
        behavior: HitTestBehavior.opaque,
        child: Container(
          width: 62,
          height: 62,
          alignment: Alignment.center,
          child: Placeholder(),
        ),
      ),
    );