How to use the AbsorbPointer widget in Flutter

The AbsorbPointer widget in Flutter is a powerful tool that allows us to control the touch interactions within a widget subtree. It can be particularly useful when we want to prevent certain user interactions, such as taps and gestures, from being detected by widgets within a specific subtree. In this Answer, we will explore how we can implement AbsorbPointer.

Constructor and parameters

The AbsorbPointer widget provides a constructor with various parameters to customize its behavior and layout.

const AbsorbPointer({
  Key? key,
  bool absorbing = true,
  Widget? child,
  bool? ignoringSemantics
})

Let's take a closer look at each parameter and its purpose:

  • key: A unique identifier for the widget.

  • absorbing: Determines if the widget should block user interactions within its subtree (true to block, false to allow).

  • child: The widget subtree where interactions should be controlled.

  • ignoringSemantics: If true, ignores the semantics of the subtree for accessibility purposes; if false, the semantics are considered.

Importing necessary libraries

Before using the AbsorbPointer widget, make sure to import the required libraries in our Dart file:

import 'package:flutter/material.dart';

Basic syntax

Here's the basic syntax of the AbsorbPointer widget:

AbsorbPointer(
absorbing: true, // Set to 'false' to allow interactions, 'true' to block interactions.
child: YourWidgetHere(),
)

Use cases

  1. Form submission: We can use AbsorbPointer to prevent users from submitting a form multiple times by blocking interactions while the form is being processed.

  2. Loading screens: When displaying a loading screen, we can use AbsorbPointer to block interactions until the loading is complete.

  3. Complex widgets: If we have complex widgets that contain multiple interactive elements, we can use the AbsorbPointer to selectively block interactions on certain parts of the widget.

  4. Error states: We can prevent users from interacting with specific UI elements when an error occurs, giving them a clear indication that those elements are not available at the moment.

Implementing the AbsorbPointer

Below we will explain a complete example of using the AbsorbPointer widget in a Flutter app:

Declare variables

The isButtonDisabled variable is used to track the disabled/enabled state of the button.

// Declare Variables
bool isButtonDisabled = false;

Function for button toggle

The _toggleButtonState function is responsible for toggling the button's disabled/enabled state.

// Function to toggle the button's disabled/enabled state
void _toggleButtonState() {
setState(() {
isButtonDisabled = !isButtonDisabled;
});
}

Function to enable button

The _enableButton function enables the initially disabled button.

// Function to enable the button
void _enableButton() {
setState(() {
isButtonDisabled = false;
});
}

Function to show snackbar

The _showSnackBar function displays a snackbar with a given message.

// Function to show a snackbar
void _showSnackBar(String message) {
final snackBar = SnackBar(
content: Text(message),
duration: Duration(seconds: 2),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}

AbsorbPointer widget

The _buildAbsorbPointerButton function creates an AbsorbPointer widget containing the main button. It controls whether interactions are absorbed based on the button's disabled state.

// Widget to create AbsorbPointer with a button
Widget _buildAbsorbPointerButton() {
return AbsorbPointer(
absorbing: isButtonDisabled,
child: ElevatedButton(
onPressed: () {
_toggleButtonState();
_showSnackBar('Button Clicked!');
},
child: Text('Click Me'),
),
);
}

Display button state

The _buildButtonStateText function creates a widget that displays the current state of the button (disabled/enabled).

// Widget to display the button's state
Widget _buildButtonStateText() {
return Text(
isButtonDisabled
? 'Button is Disabled'
: 'Button is Enabled',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: isButtonDisabled ? Colors.red : Colors.green,
),
);
}

Enable button widget

The _buildEnableButton function creates the "Enable Button" button, which, when clicked, enables the initially disabled button.

// Widget to create the "Enable Button" button
Widget _buildEnableButton() {
return ElevatedButton(
onPressed: _enableButton,
child: Text('Enable Button'),
);
}

Output

After running the above code, we can see the following output:

Code example

We get the following output by putting together the code explained above.

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'AbsorbPointer Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // Declare Variables
  bool isButtonDisabled = false;

  // Function to toggle the button's disabled/enabled state
  void _toggleButtonState() {
    setState(() {
      isButtonDisabled = !isButtonDisabled;
    });
  }

  // Function to enable the button
  void _enableButton() {
    setState(() {
      isButtonDisabled = false;
    });
  }

  // Function to show a snackbar
  void _showSnackBar(String message) {
    final snackBar = SnackBar(
      content: Text(message),
      duration: Duration(seconds: 2),
    );
    ScaffoldMessenger.of(context).showSnackBar(snackBar);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Educative AbsorbPointer Answer'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            // AbsorbPointer Widget
            _buildAbsorbPointerButton(),
            SizedBox(height: 20),
            // Display Button State
            _buildButtonStateText(),
            SizedBox(height: 20),
            // Enable Button
            _buildEnableButton(),
          ],
        ),
      ),
    );
  }

  // Widget to create AbsorbPointer with a button
  Widget _buildAbsorbPointerButton() {
    return AbsorbPointer(
      absorbing: isButtonDisabled,
      child: ElevatedButton(
        onPressed: () {
          _toggleButtonState();
          _showSnackBar('Button Clicked!');
        },
        child: Text('Click Me'),
      ),
    );
  }

  // Widget to display the button's state
  Widget _buildButtonStateText() {
    return Text(
      isButtonDisabled
          ? 'Button is Disabled'
          : 'Button is Enabled',
      style: TextStyle(
        fontSize: 18,
        fontWeight: FontWeight.bold,
        color: isButtonDisabled ? Colors.red : Colors.green,
      ),
    );
  }

  // Widget to create the "Enable Button" button
  Widget _buildEnableButton() {
    return ElevatedButton(
      onPressed: _enableButton,
      child: Text('Enable Button'),
    );
  }
}

Conclusion

The AbsorbPointer widget in Flutter provides an efficient way to control touch interactions within a specific widget subtree. Using the absorbing parameter, we can easily enable or disable interactions based on your application's logic. Providing a seamless and intuitive interface can significantly enhance the user experience.

Free Resources

Copyright ©2024 Educative, Inc. All rights reserved