Flutter: AutomaticKeepAliveClientMixin is not working with BottomNavigationBar

后端 未结 3 1229
情书的邮戳
情书的邮戳 2020-12-13 10:33

I have page called AddPatientView with BottomNavigationBar containing AddPatientInfo and AddPatientImages pages. All of these three are Stateful widgets.

By default

相关标签:
3条回答
  • 2020-12-13 10:35

    So I wrapped the tab pages in Stack widget and now it keeps the state of the form intact. I am not sure if this is the right way to go but it does the job.

    Here is the code:

    AddPatientView (parent)

    class AddPatientView extends StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        return _AddPatientViewState();
      }
    }
    
    class _AddPatientViewState extends State<AddPatientView> {
      int _currentIndex = 0;
      List<File> _imageFileList = new List<File>();
    
      @override
      void initState() {
        super.initState();
      }
    
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("New Patient Record"),
          ),
          body: new Stack(
            children: <Widget>[
              new Offstage(
                offstage: _currentIndex != 0,
                child: AddPatientInfo(savePatient),
              ),
              new Offstage(
                offstage: _currentIndex != 1,
                child: AddPatientImages(_imageFileList),
              )
            ],
          ),
          bottomNavigationBar: BottomNavigationBar(
            currentIndex: _currentIndex,
            items: [
              BottomNavigationBarItem(icon: new Icon(Icons.create), title: new Text('Info')),
              BottomNavigationBarItem(icon: new Icon(Icons.camera_alt), title: new Text('Images')),
            ],
            onTap: (int index) {
              setState(() {
                _currentIndex = index;
              });
            },
          ),
        );
      }
    }
    
    0 讨论(0)
  • 2020-12-13 10:51

    From the documentation on AutomaticKeepAliveClientMixin:

    /// A mixin with convenience methods for clients of [AutomaticKeepAlive]. Used
    /// with [State] subclasses.
    ///
    /// Subclasses must implement [wantKeepAlive], and their [build] methods must
    /// call `super.build` (the return value will always return null, and should be
    /// ignored).
    

    So in your example, before you return the Scaffold just call super.build:

      Widget build(BuildContext context) {
        super.build(context);
        return Scaffold(...);
      }
    
    0 讨论(0)
  • 2020-12-13 10:55

    If you want AutomaticKeepAliveClientMixin to continue working, please use PageView to wrap the body, the code should like this

    class AddPatientView extends StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        return _AddPatientViewState();
      }
    }
    
    class _AddPatientViewState extends State<AddPatientView> {
      int _currentIndex = 0;
      List<Widget> _children;
      List<File> _imageFileList = new List<File>();
    
      // add
      final pageController = PageController();
      void onPageChanged(int index) {
        setState(() {
          _currentIndex = index;
        });
      }
    
      @override
      void initState() {
        super.initState();
        _children = [AddPatientInfo(savePatient), AddPatientImages(_imageFileList)];
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("New Patient Record"),
          ),
          // here!!!
          body: PageView(
            children: _children,
            controller: pageController,
            onPageChanged: onPageChanged,
          ),
          bottomNavigationBar: BottomNavigationBar(
            currentIndex: _currentIndex,
            items: [
              BottomNavigationBarItem(
                  icon: new Icon(Icons.create), title: new Text('Info')),
              BottomNavigationBarItem(
                  icon: new Icon(Icons.camera_alt), title: new Text('Images')),
            ],
            onTap: (int index) {
              // setState(() {
              //   _currentIndex = index;
              // });
              // update
              pageController.jumpToPage(index);
            },
          ),
        );
      }
    }
    
    

    but if you just want to keep page state, I suggest you use IndexedStack, it's very simple,no need AutomaticKeepAliveClientMixin, the code should like this

    class AddPatientView extends StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        return _AddPatientViewState();
      }
    }
    
    class _AddPatientViewState extends State<AddPatientView> {
      int _currentIndex = 0;
      List<Widget> _children;
      List<File> _imageFileList = new List<File>();
    
      @override
      void initState() {
        super.initState();
        _children = [
          AddPatientInfo(savePatient),
          AddPatientImages(_imageFileList)
        ];
      }
    
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("New Patient Record"),
          ),
          body: IndexedStack(
            index:_currentIndex,
            children:_children
          ),
          bottomNavigationBar: BottomNavigationBar(
            currentIndex: _currentIndex,
            items: [
              BottomNavigationBarItem(icon: new Icon(Icons.create), title: new Text('Info')),
              BottomNavigationBarItem(icon: new Icon(Icons.camera_alt), title: new Text('Images')),
            ],
            onTap: (int index) {
              setState(() {
                _currentIndex = index;
              });
            },
          ),
        );
      }
    }
    
    
    
    0 讨论(0)
提交回复
热议问题