group_button icon indicating copy to clipboard operation
group_button copied to clipboard

When using Button Widgets for custom button(Indexed)Builder, onSelected will not be triggered.

Open SageMik opened this issue 1 year ago • 0 comments

When I use Button Widget such as FilledButton, ElevatedButton, etc., the internal selection event will not triggered.

Widget groupButton() {
    const buttons = ['a', 'b'];
    return GroupButton(
      buttons: buttons,
      onSelected: (value, index, selected) {
        debugPrint('onSelected'); // onSelected will not be triggered
      },
      buttonIndexedBuilder: (selected, index, context) => FilledButton(
        onPressed: () {
          debugPrint('oldSelected: $selected'); // selected is always false
        },
        child: Text(buttons[index]),
      ),
    );
  }

It's because these Buttons use InkWell, and InkWell uses a GestureDetector which prevents parent widgets from handling onTap (details here). The GestureDetector in the code below doesn't work. https://github.com/Frezyx/group_button/blob/fcb68fa51afeef9a3099ae16ce669099d9299b8b/lib/src/group_button_body.dart#L155-L166

I have tried replacing GestureDetector.onTap with Listener.onPointerDown, but it couldn't distinguish long press events. Finally I have to change button(Indexed)Builder to pass onTap argument as below:

// lib/src/utils/models/types.dart

typedef GroupButtonIndexedBuilder = Widget Function(...
  VoidCallback onTap, // add onTap argument
);
typedef GroupButtonValueBuilder<T> = Widget Function(...
  VoidCallback onTap, // add onTap argument
);
// lib/src/group_button_body.dart

if (buttonBuilder != null || buttonIndexedBuilder != null) {
        final onTap = _controller.disabledIndexes.contains(i)
            ? () => _controller.onDisablePressed?.call(i)
            : () {
          _selectButton(i);
          widget.onSelected?.call(widget.buttons[i], i, _isSelected(i));
        };
        button = buttonBuilder != null
            ? buttonBuilder(_isSelected(i), widget.buttons[i], context, onTap) // pass onTap argument
            : buttonIndexedBuilder!(_isSelected(i), i, context, onTap);
}
Widget groupButton() {...
    return GroupButton(...
      onSelected: (value, index, selected) {
        debugPrint('onSelected'); // onSelected can be triggered
      },
      buttonIndexedBuilder: (selected, index, context, onTap) => FilledButton(
        onPressed: () {
          onTap();
          debugPrint('oldSelected: $selected'); // selected can change
        },
      ...
      ),
    );
  }

So could you please fix this issue? Since I want the ripple effect of those Buttons.

SageMik avatar Mar 13 '24 08:03 SageMik