DEV Community

Cover image for Why Your InkWell Isn’t Working in Flutter (And the Widget That Fixed It)
Alpha
Alpha

Posted on

Why Your InkWell Isn’t Working in Flutter (And the Widget That Fixed It)

Have you ever had a situation where clicking on a widget isn't doing what you expect it to do? Even if you wrapped with InkWell or GestureDetector? Yeah, that was me a while ago.
I had worked on a WYSIWYG editor in a bottomsheet and when I click on the field displaying the "result" of the editor, it should display the editor. That should be pretty simple and straightforward, right? Hold my beer.
For this particular editor, I was using the popular package Flutter Quill, which is a QuillJS variation for flutter/dart. This editor isn't just there for creating the text, it also has a special way to display that text. In short, you cannot use a Text Widget to display the result of a Document (the formatted result of that editor). The Document shows you your text with all the formatting applied (Bold, Italic, Links, etc.)
First, there are all the complication that comes with formatting the text, but that's not why we are here. To display the text, we have to do this:

//create your controller
  late QuillController _quillController;

//initialise it in initState to avoid Late Initialization Error
  final json = jsonDecode( someJson ?? '[]');
      _quillController = QuillController(
        readOnly: true,
        document: Document.fromJson(json),
        selection: const TextSelection.collapsed(offset: 0),
        editorFocusNode: null,
      );

//show the content here
QuillEditor.basic(
        focusNode: null,
        controller: _quillController,
           ),
Enter fullscreen mode Exit fullscreen mode

if you're wondering what someJson is, the output of the editor often looks like so.

[
    { "insert": "Gandalf", "attributes": { "bold": true } },
    { "insert": " the Grey\n" }
  ]
Enter fullscreen mode Exit fullscreen mode

So, What's the problem with this?

The QuillEditor widget works like EditableText. Clicking the text shows a cursor, as if you're about to edit it, but you can't. And that's where our issue begins.


In my case, I need to be able to open my bottomsheet that has the editor so I can edit the "text", so I thought, just wrap it with an InkWell...

It didn't work! The onTap in my Inkwell that wraps the editor didn't take effect, the behaviour was the same - wherever I clicked, the cursor just started to blink!. Then I wrapped it the Editor with a SizedBox.
I thought, now I'm not clicking the editor, I'm clicking on the SizedBox...Wrong! I tried wrapping it with InkWell, then SizedBox, then even a decorated Container.
Nothing worked. Every tap still went straight to the editor — cursor blinking like it is in the spotlight. Until I met this widget, AbsorbPointer

The problem? QuillEditor internally handles gestures like an editable text field, so it captures all pointer events before parent widgets can react.

AbsorbPointer

AbsorbPointer is a built-in Flutter widget that prevents its subtree from receiving pointer events (touches, clicks, drags). By absorbing the editor’s touch events, the tap is no longer consumed internally — allowing the parent GestureDetector to finally respond. It acts like a transparent sheet of glass over your widgets.

How it Works
Absorbing: When absorbing: true (the default), the widget consumes the touch event. Nothing underneath it or inside it can react.

Ignoring: Unlike IgnorePointer, an AbsorbPointer still technically "occupies" space in the hit-testing tree; it just doesn't pass the event through to its children.

Apparently, that's all I've been trying to do with the SizedBox and container.

So now my widget looks like this...

              GestureDetector(
                onTap: () {
                  if (widget.isEditing) {
                    _editDescription(provider);
                  }
                },
                child: AbsorbPointer(
                  absorbing: true,
                  child: SizedBox(
                    height: _expanded ? null : 60,
                    child: QuillEditor.basic(
                      focusNode: null,
                      controller: _quillController,
                    ),
                  ),
                ),
              ),
Enter fullscreen mode Exit fullscreen mode

This adventure makes me appreciate the Flutter ecosystem and the wonderful engineers who have built hundreds of widgets for extraordinary scenarios. Those widgets you'll never know exist until you have a problem they need to solve...like mine.
Flutter has a widget for almost every edge case, but the real skill is knowing when something else is stealing your events.

For me, it was AbsorbPointer.
For you, it might be something else.
Can you share what uncommon widget you've had to use in the course of building your Flutter app?

Top comments (0)