How to update state of a ModalBottomSheet in Flutter?

前端 未结 4 2205
一个人的身影
一个人的身影 2020-12-03 02:40

This code is very simple: shows a modal bottom sheet and when the uses clicks the button, it increases the height of the sheet by 10.

But nothing happens. Actually,

相关标签:
4条回答
  • 2020-12-03 03:14

    Screenshot:


    Create a class:

    class MyBottomSheet extends StatefulWidget {
      @override
      _MyBottomSheetState createState() => _MyBottomSheetState();
    }
    
    class _MyBottomSheetState extends State<MyBottomSheet> {
      bool _flag = false;
    
      @override
      Widget build(BuildContext context) {
        return Column(
          children: [
            FlutterLogo(
              size: 300,
              style: FlutterLogoStyle.stacked,
              textColor: _flag ? Colors.black : Colors.red,
            ),
            RaisedButton(
              onPressed: () => setState(() => _flag = !_flag),
              child: Text('Change Color'),
            )
          ],
        );
      }
    }
    

    Usage:

    showModalBottomSheet(
      context: context,
      builder: (_) => MyBottomSheet(),
    );
    
    0 讨论(0)
  • 2020-12-03 03:23

    You can maybe use the showBottomSheet from the ScaffoldState. read more here about this showBottomSheet.

    This will show the bottomSheet and return a controller PersistentBottomSheetController. with this controller you can call controller.SetState((){}) which will re-render the bottomSheet.

    Here is an example

    PersistentBottomSheetController _controller; // <------ Instance variable
    final _scaffoldKey = GlobalKey<ScaffoldState>(); // <---- Another instance variable
    .
    .
    .
    void _incrementBottomSheet(){
        _controller.setState(
            (){
                heightOfModalBottomSheet += 10;
            }
        )
    }
    .
    void _createBottomSheet() async{
      _controller = await _scaffoldKey.currentState.showBottomSheet(
            context: context,
            builder: (context) {
               return Container(
                   height: heightOfModalBottomSheet,
                   child: RaisedButton(
                   onPressed: () {
                      _incrementBottomSheet()
                  }),
             );
          });
    }
    
    0 讨论(0)
  • 2020-12-03 03:28

    Please refer to the below working code. I created a new Stateful widget(ModalBottomSheet) for the showModalBottomSheet. On button press, we are rebuilding the ModalBottomSheet only which is much cleaner now. We can use AnimationController if need animation for changing the height.

    import 'dart:async';
    import 'package:flutter/material.dart';
    
    class ModalBottomSheet extends StatefulWidget {
      _ModalBottomSheetState createState() => _ModalBottomSheetState();
    }
    
    class _ModalBottomSheetState extends State<ModalBottomSheet>
        with SingleTickerProviderStateMixin {
      var heightOfModalBottomSheet = 100.0;
    
      Widget build(BuildContext context) {
        return Container(
          height: heightOfModalBottomSheet,
          child: RaisedButton(
              child: Text("Press"),
              onPressed: () {
                heightOfModalBottomSheet += 100;
                setState(() {});
              }),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        return new _MyHomePageState();
      }
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        Future(() => showModalBottomSheet(
            context: context,
            builder: (context) {
              return ModalBottomSheet();
            }));
        return new Scaffold(
          appBar: new AppBar(
            title: new Text("Modal example"),
          ),
        );
      }
    }
    
    void main() {
      runApp(new MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(title: 'Flutter Demo', home: new MyHomePage());
      }
    }
    
    0 讨论(0)
  • 2020-12-03 03:33

    You can use Flutter's StatefulBuilder to wrap your ModalBottomSheet as follows:

    showModalBottomSheet(
        context: context,
        builder: (context) {
          return StatefulBuilder(
              builder: (BuildContext context, StateSetter setState /*You can rename this!*/) {
            return Container(
              height: heightOfModalBottomSheet,
              child: RaisedButton(onPressed: () {
                setState(() {
                  heightOfModalBottomSheet += 10;
                });
              }),
            );
          });
    });
    

    Please note that the new setState will override your main widget setState but sure you can just rename it so you would be able to set state of your parent widget and the modal's

    //This sets modal state
    setModalState(() {
        heightOfModalBottomSheet += 10;
    });
    //This sets parent widget state
    setState(() {
         heightOfModalBottomSheet += 10;
    });
    
    0 讨论(0)
提交回复
热议问题