如何在 Flutter 中使用有状态小部件在所有页面中保留底部导航栏

问题描述 投票:0回答:2

我能够导航到多个不同的页面,所有页面上都有可见的底部导航栏,但无法在所有页面之间切换,那么如何在所有页面中都有底部栏的选项卡之间切换

我直到这里使用这个答案但无法使其工作,即在底部导航选项卡之间切换...

简而言之,我想为我的消息选项卡(即第二个选项卡)添加视图,并移动到它,而不会丢失我导航到的每个页面的底部导航栏...

到目前为止我的代码,

import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(home: HomePage()));

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      bottomNavigationBar: BottomNavigationBar(
        backgroundColor: Colors.orange,
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.call), label: 'Call'),
          BottomNavigationBarItem(icon: Icon(Icons.message), label: 'Message'),
        ],
      ),
      body: Navigator(
        onGenerateRoute: (settings) {
          Widget page = Page1();
          if (settings.name == 'page2') page = Page2();
          return MaterialPageRoute(builder: (_) => page);
        },
      ),
    );
  }
}

// 1st Page:

class Page1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Page1')),
      body: Center(
        child: RaisedButton(
          onPressed: () => Navigator.pushNamed(context, 'page2'),
          child: Text('Go to Page2'),
        ),
      ),
    );
  }
}

// 2nd Page:

class Page2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) => Scaffold(appBar: AppBar(title: Text('Page2')));
}
flutter dart flutter-layout tabnavigator flutter-bottomnavigation
2个回答
4
投票

尝试这样:

class HomePage extends StatefulWidget {
  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int activeIndex = 0;
  void changeActivePage(int index) {
    setState(() {
      activeIndex = index;
    });
  }

  List<Widget> pages = [];

  @override
  void initState() {
    pages = [
      Page1(() => changeActivePage(2)),
      Page2(),
      Page3(),
    ];
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        bottomNavigationBar: SizedBox(
          width: MediaQuery.of(context).size.width,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              IconButton(onPressed: () => changeActivePage(0), icon: Icon(Icons.call)),
              IconButton(onPressed: () => changeActivePage(1), icon: Icon(Icons.message)),
            ],
          ),
        ),
        body: pages[activeIndex]);
  }
}

// 1st Page:

class Page1 extends StatelessWidget {
  final Function callback;

  const Page1(this.callback);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Page1')),
      body: Center(
        child: RaisedButton(
          onPressed: () => callback(),
          child: Text('Go to Page3'),
        ),
      ),
    );
  }
}

// 2nd Page:

class Page2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) =>
      Scaffold(appBar: AppBar(title: Text('Page2')));
}

// 3rd Page:

class Page3 extends StatelessWidget {
  const Page3();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Page3')),
      body: Center(child: Text('Page3')),
    );
  }
}

0
投票

此线程重新粘贴我的解决方案。希望对以后的搜索者有所帮助。


刚刚花了一些时间探索这个问题。我决定采用 GoRouter 和 Shell Route 方法,并在 DartPad 中组合一个简单示例,以基于 this 进行测试。

第一种方法的唯一缺点是缺乏状态导航,即如果您转到内部主页和导航栏到设置然后返回,您将被发送回基本主页,而不是内部主页。幸运的是,StatefulShellRoute 存在,并且我在 github 存储库中找到了这个示例。我花了一些时间将其制作成一个更简单的示例,作为此 DartPad 中前一个示例的扩展。

享受:)

© www.soinside.com 2019 - 2024. All rights reserved.