带有索引堆栈的 Flutter bottomNavigator

tsa*_*nar 6 flutter flutter-bottomnavigation

关于使用索引堆栈在选项卡之间导航以显示相关页面的问题。我这样做是为了保持页面的滚动/状态。这工作正常。我可以通过单击选项卡更改当前显示的页面 - 也可以在每个页面内导航(每个页面都用它自己的导航器包装)。这是渲染页面的代码。

Widget build(BuildContext context) {
return IndexedStack(
    index: widget.selectedIndex,
    children: List.generate(widget._size, (index) {
  return _buildNavigator(index);
}));
Run Code Online (Sandbox Code Playgroud)

}

Mu 的问题是 IndexedStack 一次构建所有页面。在我的某些页面中,我想从 API 加载数据,我想在第一次构建小部件时执行此操作,并且仅当页面当前可见时才执行此操作。有没有办法这样做?在我当前的实现中,所有小部件都会同时构建,因此即使对于当前未绘制的页面,也会调用我的所有 API 调用。

不确定我是否在这里遗漏了什么,或者有更好的方法来实现底部导航栏。顺便说一句,我也在使用 Provider 进行状态管理。

小智 6

我遇到了同样的问题。我的解决方案是保存已加载选项卡的列表,然后使用它来构建方法IndexedStack内的子项列表Widget build(BuildContext context)。然后在onTap的方法中BottomNavigationBar,我调用setState()更新加载的选项卡列表以及当前索引变量。见下文:

class Index extends StatefulWidget {
  const Index({Key? key}) : super(key: key);

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

class _IndexState extends State<Index> {
  int _currentIndex = 0;
  List loadedPages = [0,];

  @override
  Widget build(BuildContext context) {
    var screens = [
      const FirstTab(),
      loadedPages.contains(1) ? const SecondTab() : Container(),
      loadedPages.contains(2) ? const ThirdTab() : Container(),
      loadedPages.contains(3) ? const FourthTab() : Container(),
    ];
    return Scaffold(
      appBar: AppBar(
        // AppBar
      ),
      body: IndexedStack(
        index: _currentIndex,
        children: screens,
      ),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _currentIndex,
        onTap: (index) {
          var pages = loadedPages;
          if (!pages.contains(index)) {
            pages.add(index);
          }
          setState(() {
            _currentIndex = index;
            loadedPages = pages;
          });
        },
        items: const [
          // items
        ],
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,第二个、第三个和第四个选项卡上的 API 调用在导航到之前不会调用。


小智 0

Flutter 将在堆栈内构建所有小部件,因此如果您的页面在 initState 内执行 API 调用,那么它将在构建时触发。

您可以做的是为 API 调用提供一个单独的函数。然后从导航器或状态管理中调用该函数。

我希望这可以帮助您了解如何实施这一点。