1

在应用程序中,我将PageView其用作主页和 3 个页面 - 配置文件、控制台、带有AutomaticKeepAliveClientMixin扩展名的设置。其中,2 个页面(个人资料和控制台)再次使用了“侧边菜单”屏幕PageView

问题是当我在主页之间切换时,我希望如果“侧边菜单”在任何页面上打开,它(第二个PageView)应该跳转到初始页面。

这是代码的简化版本-

材料应用-

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Home();
    );
  }
}

主页小部件 -

class Home extends StatefulWidget {
  Home({Key key}) : super(key: key);
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  int _selectedIndex = 0;
  final pageController = PageController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
                body: PageView(
                  controller: pageController,
                  physics: PageScrollPhysics(
                      parent: ScrollPhysics(
                          parent: NeverScrollableScrollPhysics())),
                  children: <Widget>[
                    Tab1(),
                    Tab2(),
                    Tab3(),
                  ],
                ),
                //to set the bottom navigation bar and not reset the entire tree
                bottomNavigationBar: StatefulBuilder(
                  builder: (BuildContext context, setState) {
                    return BottomNavigationBar(
                      currentIndex: _selectedIndex,
                      selectedItemColor: Colors.green[800],
                      onTap: (index) {
                        setState(() {
                          _selectedIndex = index;
                        });
                        pageController.jumpToPage(index);
                      },
                      items: const <BottomNavigationBarItem>[
                        BottomNavigationBarItem(
                            icon: Icon(Icons.person), label: 'Profile'),
                        BottomNavigationBarItem(
                            icon: Icon(Icons.connect_without_contact), label: 'Console'),
                        BottomNavigationBarItem(
                            icon: Icon(Icons.settings), label: 'Settings')
                      ],
                    );
                  },
                ),
              );
  }
}

同样的三页 -

class Tab1 extends StatefulWidget {
  @override
  _Tab1State createState() => _Tab1State();
}

class _Tab1State extends State<Tab1> with AutomaticKeepAliveClientMixin<Tab1> {
  final controller = PageController();

  //to use back button to go back to initial screen when poped
  bool onWillPop() {
    pageController.previousPage(
      duration: Duration(milliseconds: 200),
      curve: Curves.linear,
    );
    return false;
  }

  @override
  get wantKeepAlive {
    return true;
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);

    return PageView(
      controller: controller,
      children: [
        Scaffold(
          appBar:
              AppBar(title: Text('Profile'), backgroundColor: Colors.grey[200]),
        ),
        //so that back button brings user back to initial screen
        WillPopScope(
          onWillPop: () => Future.sync(onWillPop),
          child: Scaffold(
            appBar: AppBar(
              title: Text('Side Menu Screen'),
            ),
          ),
        )
      ],
    );
  }
}

class Tab2 extends StatefulWidget {
  @override
  _Tab2State createState() => _Tab2State();
}

class _Tab2State extends State<Tab2> with AutomaticKeepAliveClientMixin<Tab2> {
  final controller = PageController();

  //to use back button to go back to initial screen when poped
  bool onWillPop() {
    pageController.previousPage(
      duration: Duration(milliseconds: 200),
      curve: Curves.linear,
    );
    return false;
  }

  @override
  get wantKeepAlive {
    return true;
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);

    return PageView(
      controller: controller,
      children: [
        Scaffold(
          appBar:
              AppBar(title: Text('Console'), backgroundColor: Colors.grey[200]),
        ),
        //so that back button brings user back to initial screen
        WillPopScope(
          onWillPop: () => Future.sync(onWillPop),
          child: Scaffold(
            appBar: AppBar(
              title: Text('Side Menu Screen'),
            ),
          ),
        )
      ],
    );
  }
}

class Tab3 extends StatefulWidget {
  @override
  _Tab3State createState() => _Tab3State();
}

class _Tab3State extends State<Tab3> with AutomaticKeepAliveClientMixin<Tab3> {
  final controller = PageController();

  //to use back button to go back to initial screen when poped
  bool onWillPop() {
    pageController.previousPage(
      duration: Duration(milliseconds: 200),
      curve: Curves.linear,
    );
    return false;
  }

  @override
  get wantKeepAlive {
    return true;
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);

    return PageView(
      controller: controller,
      children: [
        Scaffold(
          appBar:
              AppBar(title: Text('Settings'), backgroundColor: Colors.grey[200]),
        ),
        //so that back button brings user back to initial screen
        WillPopScope(
          onWillPop: () => Future.sync(onWillPop),
          child: Scaffold(
            appBar: AppBar(
              title: Text('Side Menu Screen'),
            ),
          ),
        )
      ],
    );
  }
}

可能的方式——

  • 检测选项卡或页面何时离开屏幕并调用该controller.jumpToPage()方法。(如果可能最好)

像这样的东西-

 @override
    void dispose() {
      if (controller.hasClients) {
        controller.jumpToPage(controller.initialPage);
      }
      super.dispose();
    }
  • PageView先按onPageChanged属性听变化。
  • willPopScope检查它是否被推后弹出。

感谢你的帮助...

4

0 回答 0