Flutter: how to manage forms in tabs

953

You should use AutomaticKeepAliveClientMixin for each TabView page if you want to keep their states. Also you can you use a KeepAliveWrapper to wrap each page. Here is the code:

class KeepAliveWrapper extends StatefulWidget {
  final Widget child;

  const KeepAliveWrapper({Key key, this.child}) : super(key: key);

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

class __KeepAliveWrapperState extends State<KeepAliveWrapper>
    with AutomaticKeepAliveClientMixin {
  @override
  Widget build(BuildContext context) {
    super.build(context);
    return widget.child;
  }

  @override
  bool get wantKeepAlive => true;
}

Use it like this:

KeepAliveWrapper(
        child: Form(
          key: _formKey1,
          child: Container(),
        ),
      )

Note that before visiting each tab, your sub pages are still not built.

Share:
953
Paolo Cristofoli
Author by

Paolo Cristofoli

Updated on November 28, 2022

Comments

  • Paolo Cristofoli
    Paolo Cristofoli over 1 year

    I have a tabbar with three tabs with a different form for each one. I have a save button on the bottom to save all of them. Problem is, the three form's globalkeys currentstate are accessible only when the relative tab is active. So the formkey1.currentstate is null when I'm in tab 2 and 3, and so on. Note that I'm managing state with provider.
    Any clues on how to solve this?
    Here is a short version of the code:

    class Myclass extends StatelessWidget{  
         final  _formKey1 = GlobalKey<FormState>();
         final  _formKey2 = GlobalKey<FormState>();
         final  _formKey3 = GlobalKey<FormState>();
    
     @override
      Widget build(BuildContext context) {
        return DefaultTabController(length: 3, child:
          Scaffold(
            appBar: AppBar(
              bottom: TabBar(
                tabs: [
                  Tab(text: "TAB ONE"),
                  Tab(text: "TAB TWO"),
                  Tab(text: "TAB THREE"),
                ],
              ),
            ),
           bottomNavigationBar: 
              child: Row(
                children: [
                    FlatButton(
                      onPressed: (){
                        _save(context);
                      },
                      child: Text("Save"),
                  ),
                ],
              )
            ),
            body: TabBarView(children: [
    
              Form(key: _formKey1, ...),
              Form(key: _formKey2, ...),
              Form(key: _formKey3, ...),
          ])
        ),);
      }
    
      void _save(BuildContext context) async {
        print(_formKey1.currentState); // NULL ON TAB 2 AND 3
        print(_formKey2.currentState); // NULL ON TAB 1 AND 3
        print(_formKey3.currentState); // NULL ON TAB 1 AND 2
        //my save procedure
    }}
    
    • Paolo Cristofoli
      Paolo Cristofoli about 3 years
      I've tried to switch Myclass to be a stateful widget and I get something better results but weird and not still right, like: if I save while on tab1 I get only second form currentState=null. if I save while on tab2 I get only first form currentState=null. if I save while on tab3 I get first and second forms currentState=null.
    • Paolo Cristofoli
      Paolo Cristofoli about 3 years
      I can see in the flutter inspector that each form widget exists in the widget tree only when the relative tab is active. So currentState is null because referring to a non existing widget...