如何让 BottomNavigationBar 通过 AlertDialog 响应导航到新页面?

How can I have the BottomNavigationBar respond to navigation to a new page via AlertDialog?

我有一个 navigation_bar.dart 文件,用于处理在我的应用程序中更改为新页面的操作。在其中,我使用 bottomNavigationBar 根据当前选择的选项卡构建四个不同的页面,如下所示:

class NavigationBar extends StatefulWidget {
  @override
  _NavigationBarState createState() => _NavigationBarState();
}

class _NavigationBarState extends State<NavigationBar> {
  int _selectedIndex = 0;
  final List<Widget> _pageOptions = <Widget>[
    Page1(),
    Page2(),
    Page3(),
    Page4(),
  ];

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    String userID =
        Provider.of<FirebaseUser>(context, listen: false) != null ? Provider.of<FirebaseUser>(context).uid : 'null';

    return MultiProvider(
      providers: [StreamProvider<MyUser>.value(value: DatabaseService().streamUser(userID))],
      child: Scaffold(
        body: IndexedStack(
          children: _pageOptions,
          index: _selectedIndex,
        ),
        bottomNavigationBar: Theme(
          data: Theme.of(context).copyWith(
            canvasColor: Color(0xff271037).withOpacity(0.90),
            splashColor: Colors.transparent,
          ),
          child: BottomNavigationBar(
            currentIndex: _selectedIndex,
            onTap: _onItemTapped,
            unselectedItemColor: Colors.white,
            selectedItemColor: Color(0xff3ADEA7),
            type: BottomNavigationBarType.fixed,
            items: <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Container(),
                title: Icon(FontAwesomeIcons.fire, color: Colors.white),
              ),
              BottomNavigationBarItem(
                icon: Container(),
                title: Icon(Icons.fastfood, color: Colors.white),
              ),
              BottomNavigationBarItem(
                icon: Container(),
                title: Icon(Icons.directions_bike, color: Colors.white),
              ),
              BottomNavigationBarItem(
                icon: Container(),
                title: Icon(Icons.person, color: Colors.white),
              )
            ],
          ),
        ),
      ),
    );
  }
}

现在,在另一个文件 Page3.dart 中,该页面上会弹出一个警告对话框,单击时我希望它导航到 Page4()。

Future<void> _showMissingDataDialog(String data) async {
    return showDialog<void>(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text('You have not set your $data yet.'),
          actions: <Widget>[
            FlatButton(
              splashColor: Colors.transparent,
              highlightColor: Colors.grey[200],
              textColor: Colors.black,
              child: const Text('Cancel'),
              onPressed: () => Navigator.of(context).pop(),
            ),
            FlatButton(
                splashColor: Colors.transparent,
                highlightColor: Colors.grey[200],
                textColor: Colors.black,
                child: Text('Set $data', style: TextStyle(fontWeight: FontWeight.bold)),
                onPressed: () {
                  Navigator.of(context).pop();
                  // TODO: Redirect to page4() here as if it was tapped on the BottomNavigationBar
                })
          ],
        );
      },
    );
  }

我怎样才能拥有它以便单击“设置 $data”按钮将路由到 Page4()?我想让 bottomNavigationBar 对此做出反应,就好像您点击了实际的第四个 BottomNavigationBarItem 项目一样。

给你的导航栏一个全局键。我在我的主 Dart 文件的所有小部件之外声明了它。

GlobalKey navBarGlobalKey = GlobalKey(debugLabel: 'bottomAppBar');

bottomNavigationBar: BottomNavigationBar(
        key: navBarGlobalKey,
        onTap: _onItemTapped,
        currentIndex: _selectedIndex,
        type: BottomNavigationBarType.fixed,
        items: [ ... ]

然后使用全局键在你的按钮的onPressed方法中调用onTap方法。在全局密钥可用之前,您必须将其他 dart 文件导入此页面。

final BottomNavigationBar navigationBar = navBarGlobalKey.currentWidget;
              initialIndex = 0;
              navigationBar.onTap(3); //Starts at index 0, so passing in 3 should do the trick.