Home > Software engineering >  setState updating inside StatefulBuilder but not updating when using a method outside
setState updating inside StatefulBuilder but not updating when using a method outside

Time:07-19

I am having a showMyModalBottomSheet that calls showModalBottomSheet which returns StatefulBuilder that has some widgets. The problem i am having is that if i setState it just works fine but if i setState in a method that i have called it does not work.

Below is my showMyModalBottomSheet method


showMyModalBottomSheet() {
    showModalBottomSheet(
        context: context,
        shape: const RoundedRectangleBorder(
            borderRadius: BorderRadius.vertical(top: Radius.circular(25))),
        builder: (context) {

          return StatefulBuilder(builder: (context, setState) {
            return Container(
              padding: EdgeInsets.only(
                  bottom: MediaQuery.of(context).viewInsets.bottom),
              child: SingleChildScrollView(
                child: Container(
                  width: double.infinity,
                  child: Column(children: [
                  Container(
                    width: double.infinity,
                    margin: const EdgeInsets.only(
                        left: 10, right: 10, top: 20, bottom: 20),
                    child: Text(
                      _titleText,
                      textAlign: TextAlign.center,
                      style:
                          TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
                    ),
                  ),
                  Container(
                    width: double.infinity,
                    margin: const EdgeInsets.only(
                        left: 20, right: 20, top: 10, bottom: 10),
                    child: TextFormField(
                      key: _titleFormKey,
                      decoration: InputDecoration(labelText: "Enter Title"),
                      controller: _titleController,
                      validator: (title) {
                        if (title!.isEmpty) {
                          return "Please enter title";
                        } else {
                          return null;
                        }
                      },
                    ),
                  ),
                  Container(
                    child: ElevatedButton(
                      onPressed: () {
                        if (_titleFormKey.currentState!.validate()) {

                          // updating title
                          _titleText = _titleController.text.trim().toString();

                        }
                      },
                      child: Text("Update Title"),
                    ),
                  )
                ]),
              ),)
            );
          });
        });
  }

When i am updating my _titleText using below way it just works fine


                     onPressed: () {
                        if (_titleFormKey.currentState!.validate()) {

                          _titleText = _titleController.text.trim().toString();

                        }
                      },

But when i am using my method updateTitle like below it does not update


                     onPressed: () {
                        if (_titleFormKey.currentState!.validate()) {

                          updateTitle(_titleController.text.trim().toString());

                        }
                      },

And below is my updateTitle method


updateTitle(String title){
    setState(() {
      _titleText = title;
    });
  }

Below is my entire code


import 'package:flutter/material.dart';

class MyPage extends StatefulWidget {
  const MyPage({Key? key}) : super(key: key);

  @override
  State<MyPage> createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> {

  String _titleText = "Test Title";

  final _titleFormKey = GlobalKey<FormFieldState>();

  TextEditingController _titleController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("My Page"),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            showMyModalBottomSheet();
          },
          child: Text("Show Bottom Sheet"),
        ),
      ),
    );
  }

  showMyModalBottomSheet() {
    showModalBottomSheet(
        context: context,
        shape: const RoundedRectangleBorder(
            borderRadius: BorderRadius.vertical(top: Radius.circular(25))),
        builder: (context) {

          return StatefulBuilder(builder: (context, setState) {
            return Container(
              padding: EdgeInsets.only(
                  bottom: MediaQuery.of(context).viewInsets.bottom),
              child: SingleChildScrollView(
                child: Container(
                  width: double.infinity,
                  child: Column(children: [
                  Container(
                    width: double.infinity,
                    margin: const EdgeInsets.only(
                        left: 10, right: 10, top: 20, bottom: 20),
                    child: Text(
                      _titleText,
                      textAlign: TextAlign.center,
                      style:
                          TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
                    ),
                  ),
                  Container(
                    width: double.infinity,
                    margin: const EdgeInsets.only(
                        left: 20, right: 20, top: 10, bottom: 10),
                    child: TextFormField(
                      key: _titleFormKey,
                      decoration: InputDecoration(labelText: "Enter Title"),
                      controller: _titleController,
                      validator: (title) {
                        if (title!.isEmpty) {
                          return "Please enter title";
                        } else {
                          return null;
                        }
                      },
                    ),
                  ),
                  Container(
                    child: ElevatedButton(
                      onPressed: () {
                        if (_titleFormKey.currentState!.validate()) {

                          updateTitle(_titleController.text.trim().toString());

                        }
                      },
                      child: Text("Update Title"),
                    ),
                  )
                ]),
              ),)
            );
          });
        });
  }

  updateTitle(String title){
    setState(() {
      _titleText = title;
    });
  }
}

The problem is that its not updating text whenever i setState using updateTitle method.

CodePudding user response:

updateTitle is using state class(_MyPageState) setState, that's why it is not updating. You can pass setState of StatefulBuilder while StatefulBuilder's setState is out of scope.

updateTitle(
    _titleController.text.trim().toString(),
    setState);

And

  updateTitle(String title, setState) {
    setState(() {
      _titleText = title;
    });
  }
  • Related