# Buttons and Gestures — Flutter

Source: https://www.skillbyai.com/en/flutter/i-gestures

> Material buttons, InkWell and GestureDetector.

## Reacting to touch

Material 3 provides `FilledButton`, `ElevatedButton`, `OutlinedButton`, `TextButton` and `IconButton`; passing `onPressed: null` disables a button. **InkWell** adds a Material ripple to any area (it needs a `Material` ancestor). **GestureDetector** recognises taps, double taps, long presses, drags and scale gestures without visual feedback; competing recognisers take part in a **gesture arena** that decides which gesture wins. Higher-level widgets such as `Dismissible` (swipe to remove), `Draggable`/`DragTarget` and `InteractiveViewer` (pan and zoom) cover common interactions. Aim for touch targets of at least 48x48 logical pixels.

## Tap, long press and swipe

Buttons, InkWell and Dismissible.

```dart
Column(children: [
  FilledButton.icon(
    onPressed: isSaving ? null : save, // null disables the button
    icon: const Icon(Icons.save),
    label: const Text('Save'),
  ),
  InkWell(
    onTap: () => openDetails(item),
    onLongPress: () => showOptions(item),
    child: Padding(
      padding: const EdgeInsets.all(12),
      child: Text(item.title),
    ),
  ),
  Dismissible(
    key: ValueKey(item.id),
    onDismissed: (_) => remove(item),
    background: Container(color: Colors.red),
    child: ListTile(title: Text(item.title)),
  ),
])
```

## The gesture arena as an auction

When a finger touches the screen, every interested recogniser bids; as the finger moves, bidders drop out until one wins - a vertical drag beats a tap once the finger travels far enough.

**Quiz:** How do you disable a Material button?

- [ ] Give it a GlobalKey
- [ ] Set enabled: false on every button type
- [ ] Wrap it in a Stack
- [x] Pass null as its onPressed callback

*Answer:* Pass null as its onPressed callback. A null callback renders the disabled style and ignores taps.
