Flutter - 使用 Navigator.pop(context) 导航回页面上的特定选项卡

Flutter - navigate back to specific tab on a page with Navigator.pop(context)

在我的应用程序中,我有一个底部有 5 个选项卡的主页。在每个选项卡页面上,都有一个应用栏,其中有一个“+”符号作为操作,可将您导航到不同的页面。使用“+”按钮导航到新页面是使用以下代码以及 Flutter Platform Widgets 包完成的:

Navigator.of(context, rootNavigator: true)
    .push(
  platformPageRoute(
    context: context,
    builder: (context) => Page1(),
  ),
);

我使用 platformPageRoute 功能作为一种简单的导航方式,具有原生的感觉。现在,可以很好地导航到新页面,但是当我使用

时问题就来了
Navigator.pop(context);

导航回原始页面。当我使用它导航回原始页面时,它不会注意最初选择的选项卡。例如,如果我最初在主页的第二个选项卡上,然后使用该选项卡上的“+”按钮,最后使用

Navigator.pop(context);

在那个新页面上,它 return 是主页的第一个标签。有什么方法可以确保当我使用上述命令时,它会转到正确的选项卡?我尝试了以下方法:

Navigator.popUntil(context, '/homepageTab2');

沿着命名路线,return 到主页上的正确选项卡,尽管 return 是黑屏。为什么会这样?我也试过使用:

              Navigator.pushAndRemoveUntil(
                context,
                platformPageRoute(
                  context: context,
                  builder: (context) =>
                      HomePage(selectedPage: 1),
                ),
                (route) => false,
              );

这也不起作用,因为它 return 是 selected/correct 页面选项卡内容,但选中了第一个选项卡。此外,其他 'problem' 对我来说是动画是 'push' 而不是 'match' 我更经常使用的动画

Navigator.pop(context);

导航回屏幕。有没有一种方法可以使用 pushAndRemoveUntil 然后更改动画以匹配 pop 动画?

谢谢!

编辑:

我刚刚注意到,在我上面描述的情况下,当我使用 Navigator.pop(context); 时,它实际上 return 显示了正确的屏幕内容,但底部标签栏中的标签是在第二个选项卡的位置显示为第一个选项卡,基本上复制第一个选项卡,直到我导航到一个新选项卡并返回,此时它在正确的位置显示正确的选项卡。我希望这是有道理的!

无法使用 Navigator.

导航 TabBarView

Sub-pages

您可以在等待 Navigator.push():

后使用 TabController 转到您想要的标签页
await Navigator.of(context, rootNavigator: true)
    .push(
  platformPageRoute(
    context: context,
    builder: (context) => Page1(),
  ),
);

tabController.animateTo(<index of tab>);

事实证明,该问题与使用 Navigator.pop(context); 无关。这是我控制所选选项卡的方式。我将此作为答案发布,以防它对其他人有所帮助。

最初,我为选项卡控制器和当前选定的页面创建了 late 值,如下所示:

late TabController _tabController;
late ScrollController _scrollController;
late int _selectedPage;

然后,我创建了一个小部件列表,代表要为每个选定选项卡显示的实际页面:

List<Widget> _pageWidgets = <Widget>[
  Page1();
  Page2();
  Page3();
  Page4();
  Page5();
];

然后(我认为这是行不通的部分)我使用 initState() 如下:

  void initState() {
    super.initState();

    // Initialising a value that allows the 'final' page selector to be changed
    _selectedPage = widget.selectedPage;

    // Initialising the tab controller
    _tabController = TabController(
      length: 5,
      vsync: this,
      initialIndex: _selectedPage,
    );

    // updating the tab index when a new item is selected
    _tabController.addListener(() {
      setState(() {
        _selectedPage = _tabController.index;
        //_tabIndex = _tabController.index;
      });
    });

    // Creating the scroll controller
    _scrollViewController = ScrollController();

    // Scrolling view to top when a new tab is selected
    _tabController.addListener(() {
      setState(() {
        _scrollViewController
            .jumpTo(_scrollViewController.position.minScrollExtent);
      });
    });
  }

然后我这样控制页面内容:

body: _pageWidgets.elementAt(_selectedPage),

我不是 100% 确定为什么这不起作用,尽管我相信这与以下事实有关 initState() 只会在构建期间调用,因此将功能放在里面这意味着不会检测到更改。无论哪种方式,我的新方法都是:

  /// Controls the screen to display first
  int _index = 0;

  /// Creating a navigation key to control tab bar navigation
  final _navigationKey = GlobalKey<CurvedNavigationBarState>();

然后,在 Scaffold() 中,我显示这样的页面内容:

body: _pageWidgets.elementAt(_index),

最后,在导航栏中(来自 pub.dev 的 CurvedNavigationBar() 包)我给它一个键和索引:

key: _navigationKey,
index: _index,

这完美地控制了它,显示了正确的选项卡。