1

I want to update a text when a button is clicked inside a Modal Bottom Sheet. All widgets (text, button) are in the bottom sheet. I tried setstate, statefulbuilder but it didn't work.

I tried to use:

How to update state of...

1 Answers1

0

This was the same problem I faced when I was working with BottomSheet.

You can scroll down and copy the whole code or read the explanations.

The trick here is using a global ScaffoldKey


First Create the scaffold Key:

 final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();

then Give this key to the Scaffold:

 @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: scaffoldKey,
       .
       .
       .

For Better Code Readability I created a separate openBottomSheet Function and separate StateFulWidget class dedicated to the bottomsheet and its widgets.


The openBottomSheet function is as follows: Note: The BottomSheetWidget is the class name for bottomsheet and its widget.

void openBottomSheet() {
    print("Opening bottom Sheet");
    var sheetController = scaffoldKey.currentState
        .showBottomSheet((context) => BottomSheetWidget());
    
    // On Closure of bottom sheet:
    sheetController.closed.then((value) {
      print("Bottom Sheet Closed");
    });
  }

The BottomSheet class is a StateFulWidget class, which has two buttons and the text widget arranged in a column. You can refer the output images to get the idea about the layout.

and Bottom Sheet Code is as follows:

class BottomSheetWidget extends StatefulWidget {
  const BottomSheetWidget({
    Key key,
  }) : super(key: key);

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

class _BottomSheetWidgetState extends State<BottomSheetWidget> {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 200,
      color: Colors.amber,
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Text(text),
            RaisedButton(
              child: const Text('Change Text'),
              onPressed: () {
                text = ' Hey, The button pressed and changed the text';
                setState(() {});
                print(text);
              },
            ),
            ElevatedButton(
              child: const Text('Close BottomSheet'),
              onPressed: () => Navigator.pop(context),
            )
          ],
        ),
      ),
    );
  }
}

Here's the whole code:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

/// This is the main application widget.
class MyApp extends StatelessWidget {
  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
      home: Scaffold(
        appBar: AppBar(title: const Text(_title)),
        body: MyStateFullWidget(),
      ),
    );
  }
}

/// The text is defined here.
String text = 'hello, The Button isn\'t pressed!!!';


class MyStateFullWidget extends StatefulWidget {
  _MyStateFullWidgetState createState() => _MyStateFullWidgetState();
}

class _MyStateFullWidgetState extends State<MyStateFullWidget> {
  final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();

  //This will manage opening and closing of the bottom sheet.
  void openBottomSheet() {
    print("Opening bottom Sheet");
    var sheetController = scaffoldKey.currentState
        .showBottomSheet((context) => BottomSheetWidget());
    sheetController.closed.then((value) {
      print("Bottom Sheet Closed");
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: scaffoldKey,
      body: Center(
        child: ElevatedButton(
          child: const Text('showModalBottomSheet'),
          onPressed: () {
            openBottomSheet();
          },
        ),
      ),
    );
  }
}


// All the widgets that should go into the bottom sheet should go here.
class BottomSheetWidget extends StatefulWidget {
  const BottomSheetWidget({
    Key key,
  }) : super(key: key);

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

class _BottomSheetWidgetState extends State<BottomSheetWidget> {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 200,
      color: Colors.amber,
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Text(text),
            RaisedButton(
              child: const Text('Change Text'),
              onPressed: () {
                text = ' Hey, The button pressed and changed the text';
                setState(() {});
                print(text);
              },
            ),
            ElevatedButton(
              child: const Text('Close BottomSheet'),
              onPressed: () => Navigator.pop(context),
            )
          ],
        ),
      ),
    );
  }
}

Before pressing the Button Output: enter image description here

After pressing the Button Output: enter image description here


Hope this helps:

Adithya Shetty
  • 1,247
  • 16
  • 30