Home > Enterprise >  A method assigned to IconButton (onPressed) is called automatically on state initialisation
A method assigned to IconButton (onPressed) is called automatically on state initialisation

Time:10-24

I try to show an overlapping widget which is being added to a stack when the appropriate button is pressed. Here is simplified example of the code:

...

class _MyApp extends State<MyApp> {
    bool _isFloatingWidgetShown = false;

    @override
    Widget build(BuildContext context) {

        void _showFloatingWidget() {
            setState(() {
                _isFloatingWidgetShown = true;
            });
        }

        void _hideFloatingWidget() {
            setState(() {
                _isFloatingWidgetShown = false;
            });
        }

        return MaterialApp(
            home: Scaffold(
                body: Container(
                    child: Stack(
                        children: [
                            ...
                            if (_isFloatingWidgetShown) MyFloatingWidget(onClose: _hideFloatingWidget)
                            ]
                            ...

class MyFloatingWidget extends StatefulWidget {
  const MyFloatingWidget(
      {Key? key, required this.onClose})
      : super(key: key);

  final Function onClose;
  ...

class _MyFloatingWidget extends State<MyFloatingWidget> {
@override
Widget build(BuildContext context) {
   return IconButton(
                   onPressed: widget.onClose(),
                   icon: Icon(
                       Icons.close))
                   ...

But once the widget is shown it immediately calls _hideFloatingWidget method and I get the following error: FlutterError (setState() or markNeedsBuild() called during build...

Why does it call assigned to onPressed method by itself during state initialization?

CodePudding user response:

You should not use (if not necessary) functions in build method. When you do this, do not use setState in it. Just _showFloatingWidget and _hideFloatingWidget use out of the build method. "build" method is calling whenever you show the screen or when you use "setState". It calls the function because of it.

    @override
Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
            body: Container(
                child: Stack(
                    children: [
                        ...
                        if (_isFloatingWidgetShown) MyFloatingWidget(onClose: _hideFloatingWidget)
                        ]
                        ...
} 

void _showFloatingWidget() {
    setState(() {
        _isFloatingWidgetShown = true;
    });
}

void _hideFloatingWidget() {
    setState(() {
        _isFloatingWidgetShown = false;
    });
}

CodePudding user response:

The solution is to use the following method notation for onPressed property of IconButton:

...
onPressed: () {
     widget.onClose();
}
...
  • Related