IconButton and long press detection

Viewed 2266

Please help me with long press detection on an icon button.

I'm trying to get an icon button that will change the quantity value by 1 if tapped and by 10 while long pressed. The problem is that there is no a long press event handler available for the IconButton in Flutter 2.12 unfortunately.

So I used just the Icon inside the Container as below

        GestureDetector(
          child: Container(
            child: const Icon(
              Icons.add,
            ),
            padding: EdgeInsets.symmetric(vertical: 6.0, horizontal: 18.0),
          ),
          onTap: () {
            increment(1);
          },
          onLongPressStart: (_) async {
            startPressing(() => increment(10));
          },
          onLongPressCancel: () {
            cancelPress();
          },
          onLongPressEnd: (_) {
            cancelPress();
          },
        ),

it is working but the problem is that press area is very small and it is uncomfortable to find a press point while on the mobile.

I've tried to increase the icon size to 48 but the result is awful the icon is unnatural big

const Icon(
              Icons.add,
              size: 48,
            ),

the design that looks fine for me is to use the GestureDetector (for long press) with IconButton (and onPressed for single tap detection):

        GestureDetector(
          child: IconButton(
            onPressed: () => decrement(1),
            icon: const Icon(
              Icons.remove,
            ),
            padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 18.0),
            color: Theme.of(context).primaryColor,
          ),
          onLongPressStart: (_) async {
            startPressing(() => decrement(10));
          },
          onLongPressCancel: () {
            cancelPress();
          },
          onLongPressEnd: (_) {
            cancelPress();
          },
        ),

is it fine for Flutter to have the GestureDetector for longPress and the IconButton for onPressed ? May I have some trouble on some specific Android version with such solution?

2 Answers

Try with InkWell instead, it will act like IconButton and gives you ripple effect

Material(
  child: InkWell(
    onTap: () {},
    onLongPress: () {},
    child: Ink(
      child: Icon(Icons.add),
    ),
  ),
),

set up width and height to Container and put into GestureDetector and fix size by padding of Icon

     Container(
      alignment: Alignment.center,
      width: 40, 
      height: 40,
      child: GestureDetector(
        child: Padding(
         padding: EdgeInsets.symmetric(vertical: 6.0, horizontal: 18.0),
         child: Icon(
          Icons.add,
      ),),
      onTap: () {
        increment(1);
      },
      onLongPressStart: (_) async {
        startPressing(() => increment(10));
      },
      onLongPressCancel: () {
        cancelPress();
      },
      onLongPressEnd: (_) {
        cancelPress();
      },
    ),
   )
Related