skip to Main Content

I have this widget:

InkWell(
  onTap: () {
    print('Tapped');
  },
  child: Row(
    mainAxisAlignment: MainAxisAlignment.spaceAround,
    children: [
      Text('Text'),
      TextButton( // <- I tried to wrap it with AbsorbPointer.
        child: Text('Disable'),
        onPressed: null,
      ),
    ],
  ),
),

It is an InkWell with an onTap (in this example, it only prints 'Tapped'), and inside there is a button that can be (not all the time) disabled.

My issue is that when the TextButton is disabled, clicking on it triggers the onTap of the InkWell. I would like to block this and if the user clicks on the disable button, nothing happens.

I tried to wrap the TextButton with an AbsorbPointer but it didn’t work.

How can I do that?

2

Answers


  1. You can sync the state of InkWell and TextButton.

    // Wrapping this inside a Stateful Widget
    bool isEnable = false; // This is state of InkWell and TextButton
    
    // Your widget
    InkWell(
      onTap: isEnable
        ? () {
          print('Tapped');
        }
        : null,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          Text('Text'),
          TextButton(
            child: Text('Disable'),
            onPressed: isEnable
              ? () {
                // Your actions
              }
              : null,
          ),
        ],
      ),
    ),
    
    // and you can change both widgets state by using `setState`
    setState(() {
      isEnable = !isEnable;
    });
    
    

    It will be better if you move your actions out of widget codes

    // Wrapping this inside a Stateful Widget
    bool isEnable = false; // This is state of InkWell and TextButton
    
    void _inkWellActions() {}
    
    void _textButtonActions() {}
    
    // Your widget
    InkWell(
      onTap: isEnable
        ? _inkWellActions
        : null,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          Text('Text'),
          TextButton(
            child: Text('Disable'),
            onPressed: isEnable
              ? _textButtonActions
              : null,
          ),
        ],
      ),
    ),
    
    Login or Signup to reply.
  2. if you want to keep the ripple effect from the inkwell without executing something when the inkwell is tapped, dont set the onTap parameter to null, set to ontap: (){} instead

    here’s the example

    import 'package:flutter/material.dart';
    
    class SomeWidget extends StatefulWidget {
      const SomeWidget({Key? key}) : super(key: key);
    
      @override
      State<SomeWidget> createState() => _SomeWidgetState();
    }
    
    class _SomeWidgetState extends State<SomeWidget> {
      bool isEnable = false;
    
      @override
      Widget build(BuildContext context) {
        return InkWell(
          onTap: isEnable
              ? executeSomething
              : () {
                  // just let this empty
                },
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              Text('Text'),
              TextButton(
                child: Text('Disable'),
                onPressed: isEnable ? executeSomething : null,
              ),
            ],
          ),
        );
      }
    
      void executeSomething() {
        print('Tapped');
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search