Losing widget state when switching pages in a Flutter PageView

前端 未结 3 2047
隐瞒了意图╮
隐瞒了意图╮ 2020-12-23 21:07

I have a series of stateful widgets in a PageView managed by a PageController. I am using pageController.jumpToPage(index) to switch pages. When switching pages

相关标签:
3条回答
  • 2020-12-23 21:29

    keepPage: true is the default behavior; it means that the PageController will remember what page it's on if it is destroyed and recreated. This isn't what you want.

    Instead, pass a page-specific PageStorageKey to the constructor of the pages. This helps Flutter give a unique storage bucket to your page. Then in your State that you want to have restored to its previous condition, you can use PageStorage.of(context) to get the storage bucket, which you can read values from in initState and write values to when they change. You can see an example in ExpansionTile.

    0 讨论(0)
  • 2020-12-23 21:51

    use with AutomaticKeepAliveClientMixin to your SubPage.

    then @override bool get wantKeepAlive => true; here is a sample

    import 'package:flutter/material.dart';
    
    void main() => runApp(new MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'Flutter Demo',
          theme: new ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: new MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => new _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return DefaultTabController(
          length: 4,
          child: new Scaffold(
            appBar: new AppBar(
              bottom: new TabBar(
                tabs: [
                  new Tab(icon: new Icon(Icons.directions_car)),
                  new Tab(icon: new Icon(Icons.directions_transit)),
                  new Tab(icon: new Icon(Icons.directions_bike)),
                  new Tab(
                    icon: new Icon(Icons.airplanemode_active),
                  )
                ],
              ),
            ),
            body: new TabBarView(children: [
              new OnePage(color: Colors.black,),
              new OnePage(color: Colors.green,),
              new OnePage(color: Colors.red,),
              new OnePage(color: Colors.blue,),
            ]),
          ),
        );
      }
    }
    
    class OnePage extends StatefulWidget {
      final Color color;
    
      const OnePage({Key key, this.color}) : super(key: key);
    
      @override
      _OnePageState createState() => new _OnePageState();
    }
    
    class _OnePageState extends State<OnePage> with AutomaticKeepAliveClientMixin<OnePage> {
      @override
      Widget build(BuildContext context) {
        super.build(context);
        return new SizedBox.expand(
          child: new ListView.builder(
            itemCount: 100,
            itemBuilder: (context, index) {
              return new Padding(
                padding: const EdgeInsets.all(10.0),
                child: new Text(
                  '$index',
                  style: new TextStyle(color: widget.color),
                ),
              );
            },
          ),
        );
      }
    
      @override
      bool get wantKeepAlive => true;
    }
    
    0 讨论(0)
  • 2020-12-23 21:53

    Write custom widget:

    import 'package:flutter/material.dart';
    
    class KeepAlivePage extends StatefulWidget {
      KeepAlivePage({
        Key key,
        @required this.child,
      }) : super(key: key);
    
      final Widget child;
    
      @override
      _KeepAlivePageState createState() => _KeepAlivePageState();
    }
    
    class _KeepAlivePageState extends State<KeepAlivePage>
        with AutomaticKeepAliveClientMixin {
      @override
      Widget build(BuildContext context) {
        /// Dont't forget this
        super.build(context);
    
        return widget.child;
      }
    
      @override
      // TODO: implement wantKeepAlive
      bool get wantKeepAlive => true;
    }
    

    And use in pageview:

    import 'package:flutter/material.dart';
    import 'keep_alive_page.dart';
    class PageViewDemo extends StatefulWidget {
      const PageViewDemo({Key key}) : super(key: key);
    
      @override
      _PageViewDemoState createState() => _PageViewDemoState();
    }
    
    class _PageViewDemoState extends State<PageViewDemo> {
      @override
      Widget build(BuildContext context) {
        return PageView(
          children: [
            KeepAlivePage(child:Page1()),
            KeepAlivePage(child: Page2()),
            KeepAlivePage(child:Page3()),
          ],
        );
      }
    }
    
    0 讨论(0)
提交回复
热议问题