Flutter 如何在Flatter中以编程方式切换BottomNavigationBar选项卡(以及在页面之间导航)

Flutter 如何在Flatter中以编程方式切换BottomNavigationBar选项卡(以及在页面之间导航),flutter,dart,navigation,bottomnavigationview,Flutter,Dart,Navigation,Bottomnavigationview,我使用的是全新的flutter,所以任何好的建议都会对我有帮助 我正在创建一个有三个页面的应用程序-一个主页,一个详细信息页面和一个设置页面。因此,在我的主页代码中,在提交一些数据后,用户将被带到第二页(即详细信息页) 我正在使用曲线导航栏[]包作为我的底部导航栏 HomeView.dart import 'package:curved_navigation_bar/curved_navigation_bar.dart'; //necessary imports class HomeView

我使用的是全新的flutter,所以任何好的建议都会对我有帮助

我正在创建一个有三个页面的应用程序-一个主页,一个详细信息页面和一个设置页面。因此,在我的主页代码中,在提交一些数据后,用户将被带到第二页(即详细信息页)

我正在使用曲线导航栏[]包作为我的底部导航栏

HomeView.dart

import 'package:curved_navigation_bar/curved_navigation_bar.dart';
//necessary imports

class HomeView extends StatefulWidget {
  final GlobalKey globalKey;

  HomeView(this.globalKey);

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

class _HomeViewState extends State<HomeView> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: //SomeButton(
        onPressed: () => {
          final CurvedNavigationBar navigationBar = widget.globalKey.currentWidget;
          navigationBar.onTap(1);  //<-This is the line where user will be taken to page 2
        }
      ),
    );
  }
}
import 'package:curved_navigation_bar/curved_navigation_bar.dart';
//necessary imports

class NavBar extends StatefulWidget {
  NavBar({Key key}) : super(key: key);

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

class _NavBarState extends State<NavBar> {
  GlobalKey globalKey = new GlobalKey(debugLabel: 'btm_app_bar');
  ChatSessionDetails _chatSessionDetails = ChatSessionDetails();

  int _currentIndex;
  String _appBarTitle;

  List<Widget> pages = [];

  final PageStorageBucket bucket = PageStorageBucket();

  void initState() {
    super.initState();

    pages = [
      HomeView(globalKey),
      ChatView(key: PageStorageKey('ChatPage')),
      SettingsView()
    ];

    _currentIndex = 0;
    _appBarTitle = 'HomePage';
  }

  void changeTab(int index) {      //<-PageChange logic
    switch (index) {
      case 0:
        setState(
          () => {
            _appBarTitle = 'HomePage',
            _currentIndex = 0,
          },
        );
        break;
      case 1:
        if (_sessionDetails.file != null) {
          setState(
            () => {
              _appBarTitle = //some title,
              _currentIndex = 1
            },
          );
        } else {
          ScaffoldMessenger.of(context).showSnackBar(SnackBar(
            content: Text('You haven\'t opened a session yet'),
            behavior: SnackBarBehavior.floating,
          ));
        }
        break;
      case 2:
        setState(
          () => {
            _appBarTitle = 'Settings',
            _currentIndex = 2,
          },
        );
        break;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(_appBarTitle),
      ),
      body: PageStorage(
        child: pages[_currentIndex],
        bucket: bucket,
      ),
      extendBody: true,
      bottomNavigationBar: CurvedNavigationBar(
        key: globalKey,        items: <Widget>[
          Icon(Icons.home_rounded, size: 30, color: Colors.grey[600]),
          Icon(CustomIcons.whatsapp, size: 30, color: Colors.grey[600]),
          Icon(Icons.settings_rounded, size: 30, color: Colors.grey[600]),
        ],
        onTap: (index) {
          changeTab(index); //Handle button tap
        },
      ),
    );
  }
}

import'包:弧形导航栏/弧形导航栏.dart';
//必要进口
类HomeView扩展了StatefulWidget{
最终的GlobalKey-GlobalKey;
HomeView(这是globalKey);
@凌驾
_HomeViewState createState();
}
类_HomeViewState扩展了状态{
@凌驾
小部件构建(构建上下文){
返回容器(
child://SomeButton(
按下:()=>{
最终曲线导航栏导航栏=widget.globalKey.currentWidget;
navigationBar.onTap(1);//_NavBarState();
}
类_NavBarState扩展状态{
GlobalKey GlobalKey=新的GlobalKey(debugLabel:'btm_app_bar');
ChatSessionDetails _ChatSessionDetails=ChatSessionDetails();
int currentIndex;
字符串_appBarTitle;
列表页=[];
final PageStorageBucket bucket=PageStorageBucket();
void initState(){
super.initState();
页数=[
HomeView(环球银行),
ChatView(键:PageStorageKey('ChatPage')),
设置视图()
];
_currentIndex=0;
_appBarTitle=‘主页’;
}
void changeTab(int索引){//{
_appBarTitle='主页',
_currentIndex=0,
},
);
打破
案例1:
if(_sessionDetails.file!=null){
设定状态(
() => {
_appBarTitle=//一些标题,
_currentIndex=1
},
);
}否则{
ScaffoldMessenger.of(上下文)。showSnackBar(SnackBar(
内容:Text(“您尚未打开会话”),
行为:SnackBarBehavior.floating,
));
}
打破
案例2:
设定状态(
() => {
_appBarTitle='设置',
_currentIndex=2,
},
);
打破
}
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(_appBarTitle),
),
正文:页面存储(
子:页面[_currentIndex],
桶:桶,
),
扩展体:是的,
底部导航栏:曲线导航栏(
关键字:globalKey,项目:[
图标(Icons.home_圆角,尺寸:30,颜色:Colors.grey[600]),
图标(CustomIcons.whatsapp,尺寸:30,颜色:Colors.grey[600]),
图标(Icons.settings_圆角,大小:30,颜色:Colors.grey[600]),
],
onTap:(索引){
更改选项卡(索引);//手柄按钮点击
},
),
);
}
}
整个导航工作进行得很顺利,但当我以编程方式调用
changeTab()
函数时(而不是通过单击底部导航选项卡来调用),事情变得很奇怪

下面是gif的链接

选项卡应该更改,因为我没有将状态更改为
\u sessionDetails.file!=null

false
。如何避免此问题?

在changeTab中,您需要使用键来更改页面:

globalKey.currentState.setPage(1);
[更新]

作者的官方方式:

以编程方式更改页面

  //State class
  int _page = 0;
  GlobalKey _bottomNavigationKey = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        bottomNavigationBar: CurvedNavigationBar(
          key: _bottomNavigationKey,
          items: <Widget>[
            Icon(Icons.add, size: 30),
            Icon(Icons.list, size: 30),
            Icon(Icons.compare_arrows, size: 30),
          ],
          onTap: (index) {
            setState(() {
              _page = index;
            });
          },
        ),
        body: Container(
          color: Colors.blueAccent,
          child: Center(
            child: Column(
              children: <Widget>[
                Text(_page.toString(), textScaleFactor: 10.0),
                RaisedButton(
                  child: Text('Go To Page of index 1'),
                  onPressed: () {
                    //Page change using state does the same as clicking index 1 navigation button
                    final CurvedNavigationBarState navBarState =
                        _bottomNavigationKey.currentState;
                    navBarState.setPage(1);
                  },
                )
              ],
            ),
          ),
        ));
  }
//状态类
int _page=0;
GlobalKey _bottomNavigationKey=GlobalKey();
@凌驾
小部件构建(构建上下文){
返回脚手架(
底部导航栏:曲线导航栏(
键:_bottomNavigationKey,
项目:[
图标(Icons.add,大小:30),
图标(图标列表,大小:30),
图标(图标。比较箭头,尺寸:30),
],
onTap:(索引){
设置状态(){
_页面=索引;
});
},
),
主体:容器(
颜色:Colors.blueAccent,
儿童:中心(
子:列(
儿童:[
Text(_page.toString(),textScaleFactor:10.0),
升起的按钮(
子项:文本(“转到索引1的第页”),
已按下:(){
//使用状态进行页面更改与单击索引1导航按钮相同
最终曲线导航栏状态导航栏状态=
_bottomNavigationKey.currentState;
navBarState.setPage(1);
},
)
],
),
),
));
}

仍然不起作用。我已经更新了答案,您应该按照作者提供的方式进行操作