Home > Software engineering >  How to update state of a ModalBottomSheet widget in Flutter?
How to update state of a ModalBottomSheet widget in Flutter?

Time:10-15

I'm trying to change the state of the screen through a StatefulBuilder ModalBottomSheet widget. But precisely by changing the background color of the main.dart screen. But the widget state change does not happen.

My question is: how do I call the update state of a StatefulBuilder ModalBottomSheet in another widget?

main.dart

    import 'package:flutter/material.dart';
    import 'package:modal.dart';
    
    bool isEnable = false;
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: const MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      const MyHomePage({super.key, required this.title});
    
      final String title;
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: isEnable ? Colors.amber : Colors.white,
          appBar: AppBar(
            title: Text(widget.title),
            centerTitle: true,
          ),
          body: Container(),
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              showModalBottomSheet(
                  shape: const RoundedRectangleBorder(
                    borderRadius: BorderRadius.vertical(top: Radius.circular(15.0)),
                  ),
                  backgroundColor: Colors.white,
                  context: context,
                  isScrollControlled: true,
                  builder: (context) {
                    return const ModalBottomSheet();
                  });
            },
            child: const Icon(Icons.change_circle_outlined),
          ),
        );
      }
    }


modal.dart


import 'package:flutter/material.dart';
import 'package:main.dart';

class ModalBottomSheet extends StatefulWidget {
  const ModalBottomSheet({super.key});

  @override
  _ModalBottomSheetState createState() => _ModalBottomSheetState();
}

class _ModalBottomSheetState extends State<ModalBottomSheet> {
  bool light = true;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return StatefulBuilder(builder: (BuildContext context, StateSetter state) {
      return Wrap(
        children: <Widget>[
          SafeArea(
            child: Padding(
                padding:
                    EdgeInsets.only(top: MediaQuery.of(context).padding.top),
                child: SingleChildScrollView(
                  child: Center(
                    child: Column(
                      mainAxisSize: MainAxisSize.min,
                      children: <Widget>[
                        Text(isEnable.toString()),
                        Switch(
                          value: light,
                          activeColor: Colors.red,
                          onChanged: (bool value) {
                            state(() {
                              light = value;
                              isEnable = value;
                            });
                          },
                        )
                      ],
                    ),
                  ),
                )),
          )
        ],
      );
    });
  }
}

CodePudding user response:

how do I call the update state of a StatefulBuilder ModalBottomSheet in another widget?

To update the state of a widget from another widget somewhere else in the tree, you need some sort of scoped or global application state. I'd recommend taking a look at riverpod, but there are a multitude of other state management approaches out there.

CodePudding user response:

To update the values on a screen from a modal you can either use a state management solution or expose a function that returns the updated values to the parent widget. this works

import 'package:flutter/material.dart';
import 'package:modal.dart';

bool isEnable = false;
void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: isEnable ? Colors.amber : Colors.white,
      appBar: AppBar(
        title: Text(widget.title),
        centerTitle: true,
      ),
      body: Container(),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          showModalBottomSheet(
              shape: const RoundedRectangleBorder(
                borderRadius: BorderRadius.vertical(top: Radius.circular(15.0)),
              ),
              backgroundColor: Colors.white,
              context: context,
              isScrollControlled: true,
              builder: (context) {
                return ModalBottomSheet(onSwitch: (bool value) {
                  setState(() {
                    isEnable = !isEnable;
                  });
                });
              });
        },
        child: const Icon(
          Icons.change_circle_outlined,
        ),
      ),
    );
  }
}

modal.dart

class ModalBottomSheet extends StatefulWidget {
  const ModalBottomSheet({super.key,required this.onSwitch});
  final Function(bool value) onSwitch;

  @override
  _ModalBottomSheetState createState() => _ModalBottomSheetState();
}

class _ModalBottomSheetState extends State<ModalBottomSheet> {
  bool light = true;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return StatefulBuilder(builder: (BuildContext context, StateSetter state) {
      return Wrap(
        children: <Widget>[
          SafeArea(
            child: Padding(
                padding:
                    EdgeInsets.only(top: MediaQuery.of(context).padding.top),
                child: SingleChildScrollView(
                  child: Center(
                    child: Column(
                      mainAxisSize: MainAxisSize.min,
                      children: <Widget>[
                        Text(isEnable.toString()),
                        Switch(
                          value: light,
                          activeColor: Colors.red,
                          onChanged: (bool value) {
                            setState(() {
                              light = !light;
                            });

                            widget.onSwitch!(value);
                          },
                        )
                      ],
                    ),
                  ),
                ),
             ),
          )
        ],
      );
    });
  }
}
  • Related