StatefulWidget Page recreate when keyboard is open

7,300

Solution 1

You should move your variable isUpdate inside your State, remember the widget is inmutable.

        class UpdateProfileState extends State<UpdateProfile> {

         bool isUpdate = false;

          @override
          Widget build(BuildContext context) {
            // TODO: implement build
            return Scaffold(
              appBar: AppBar(
                  title: Text("Update"),
                  elevation: 2.0),
              body: Container(
                width: double.infinity,
                height: double.infinity,
                color: Colors.red,
                margin: const EdgeInsets.all(10.0),
                child: Row(
                  children: <Widget>[
                    isUpdate ? new Flexible(child: new TextField()) : Text("Text Widget"),
                    GestureDetector(
                      child: IconTheme(
                          data: IconThemeData(color: Color(0xFFffffff)),
                          child: Icon(Icons.edit)),
                      onTap: () {
                        setState(() {
                          isUpdate = !isUpdate;
                        });
                      },
                    )
                  ],
                ),
              ),
            );
          }
        }

And also change this:

    Navigator.push(context,MaterialPageRoute(builder: (context) => UpdateProfile()))

To this:

    final page = UpdateProfile();
    Navigator.push(context,MaterialPageRoute(builder: (context) => page ))

Solution 2

as an addition, if you do something on didChangeDependencies method, thats also gonna cause that

Share:
7,300
Magesh Pandian
Author by

Magesh Pandian

Techie by Birth. Observer by Nature. Unpredictable by Character. Mobile Developer by Profession.

Updated on December 08, 2022

Comments

  • Magesh Pandian
    Magesh Pandian over 1 year

    In my profile page have edit option when use click edit icon i change Text widget to TextField Widget using Boolean condition like
    widget.isUpdate ? new Flexible(child: new TextField()) : Text("Text Widget") it working but when TextField focused the keyboard is open on that time StatefulWidget recreate so again Boolean became false then Textfield move to Text Widget. This scenario only happen when page has Navigator push page (Second Page) like

     Navigator.push(context,MaterialPageRoute(builder: (context) => UpdateProfile()))
    

    if this page as default home page then work fine. I don't what mistake i done.

    Code :

    import 'package:flutter/material.dart';
    
    class UpdateProfile extends StatefulWidget {
      bool isUpdate = false;
    
      @override
      State<StatefulWidget> createState() {
        // TODO: implement createState
        return UpdateProfileState();
      }
    }
    
    class UpdateProfileState extends State<UpdateProfile> {
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return Scaffold(
          appBar: AppBar(
              title: Text("Update"),
              elevation: 2.0),
          body: Container(
            width: double.infinity,
            height: double.infinity,
            color: Colors.red,
            margin: const EdgeInsets.all(10.0),
            child: Row(
              children: <Widget>[
                widget.isUpdate ? new Flexible(child: new TextField()) : Text("Text Widget"),
                GestureDetector(
                  child: IconTheme(
                      data: IconThemeData(color: Color(0xFFffffff)),
                      child: Icon(Icons.edit)),
                  onTap: () {
                    setState(() {
                      widget.isUpdate = !widget.isUpdate;
                    });
                  },
                )
              ],
            ),
          ),
        );
      }
    }
    

    Issue :

    If i set as home page then work fine like below

    import 'package:expense_manager_app/page/splash_page.dart';
    import 'package:expense_manager_app/page/update_profile.dart';
    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          title: 'Flutter Demo',
          theme: ThemeData(
            // This is the theme of your application.
            //
            // Try running your application with "flutter run". You'll see the
            // application has a blue toolbar. Then, without quitting the app, try
            // changing the primarySwatch below to Colors.green and then invoke
            // "hot reload" (press "r" in the console where you ran "flutter run",
            // or simply save your changes to "hot reload" in a Flutter IDE).
            // Notice that the counter didn't reset back to zero; the application
            // is not restarted.
            brightness: Brightness.dark,
            primaryColor: Colors.red[500],
            accentColor: Colors.green[900],
          ),
          home: UpdateProfile(),
        );
      }
    }
    
  • Magesh Pandian
    Magesh Pandian over 5 years
    if i set in initState not in default then it throws error boolean expression must not be null
  • Magesh Pandian
    Magesh Pandian over 5 years
    yep i already tired its working but why its not working when this page as second page like Navigator push. how its working as home default page.
  • iPatel
    iPatel over 5 years
    @MageshPandian then put bool isUpdate; in your state class and just remove widget prefix in initState method.
  • Magesh Pandian
    Magesh Pandian over 5 years
    yes already did it working but my doubt why it recreate or reinitialize during keyboard open when page as second page not as home page
  • diegoveloper
    diegoveloper over 5 years
    Did you change the push like I wrote above?
  • Magesh Pandian
    Magesh Pandian over 5 years
    after set as final its working so my doubt is if i directly mention inside MaterialPageRoute then each time it recreate the object ?
  • diegoveloper
    diegoveloper over 5 years
    Yeah all the content inside the builder is recreated , for that reason you have to extract the widget in a variable