首页 > 解决方案 > 通过更改 AppBar 持久化 BottomNavigationBar

问题描述

因此,我正在创建一个具有 5 个 BottomNavigationBarItem(s) 的屏幕,该屏幕在理想情况下会持续存在,而 AppBar 会根据设计进行更改。这是我的代码:

class ExploreState extends State<ExploreScreen> {
  int _selectedIndexForBottomNavigationBar = 0;

  void _onItemTappedForBottomNavigationBar(int index) {
    setState(() {
      _selectedIndexForBottomNavigationBar = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new DefaultTabController(
      length: 3,
      child: new Scaffold(
        appBar: AppBar(
          bottom: ColoredTabBar(
            color: Colors.white,
            tabBar: TabBar(
              labelColor: Colors.grey[900],
              indicator: UnderlineTabIndicator(
                borderSide: BorderSide(color: kPrimaryColor, width: 2.0),
              ),
              tabs: <Widget>[
                Tab(text: "Job Posts"),
                Tab(
                  text: "Agencies",
                ),
                Tab(
                  text: "All Applicants",
                ),
              ],
            ),
          ),
          elevation: 0.7,
          centerTitle: true,
          title: Text(
            "Looking For",
            style: TextStyle(fontSize: 18),
          ),
          actions: <Widget>[
            Icon(Icons.search),
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 5.0),
            ),
          ],
        ),
        body: TabBarView(
          children: <Widget>[
            Jobs(),
            Agencies(),
            Applicants(),
          ],
        ),
        bottomNavigationBar: BottomNavigationBar(
          type: BottomNavigationBarType.fixed,
          items: <BottomNavigationBarItem>[
            _bottomNavigationBarItem(
                AssetImage("assets/images/search-job.png"), 'Explore'),
            _bottomNavigationBarItem(
                AssetImage("assets/images/message.png"), 'Messaging'),
            _bottomNavigationBarItem(
                AssetImage("assets/images/forums.png"), 'Forums'),
            _bottomNavigationBarItem(
                AssetImage("assets/images/notifications.png"), 'Notifications'),
            _bottomNavigationBarItem(
                AssetImage("assets/images/profile.png"), 'Edit Profile'),
          ],
          currentIndex: _selectedIndexForBottomNavigationBar,
          selectedItemColor: kPrimaryColor,
          onTap: _onItemTappedForBottomNavigationBar,
          selectedFontSize: 0,
        ),
      ),
    );
  }

  BottomNavigationBarItem _bottomNavigationBarItem(
      AssetImage icon, String label) {
    return BottomNavigationBarItem(
      activeIcon: _navItemIcon(
          icon, label, [kPrimaryColor, kPrimaryWelcomeColor], Colors.white),
      icon: _navItemIcon(
          icon, label, [Colors.white, Colors.white], Color(0xFF4E5969)),
      label: "",
    );
  }

  Row _navItemIcon(AssetImage icon, String label, List<Color> backgrondColor,
      Color? foregroundColor) {
    return Row(
      children: [
        Expanded(
          child: Container(
            decoration: BoxDecoration(
              gradient: LinearGradient(
                begin: Alignment.bottomLeft,
                end: Alignment.topRight,
                colors: backgrondColor,
                transform: GradientRotation(1.5),
              ),
            ),
            child: Padding(
              padding: const EdgeInsets.all(15.0),
              child: Column(
                children: [
                  ImageIcon(
                    icon,
                    size: 25,
                    color: foregroundColor,
                  ),
                  Text(
                    label,
                    style: TextStyle(color: foregroundColor, fontSize: 8),
                  )
                ],
              ),
            ),
          ),
        ),
      ],
    );
  }
}

class ColoredTabBar extends Container implements PreferredSizeWidget {
  ColoredTabBar({this.color = Colors.white, this.tabBar});

  final Color color;
  final TabBar? tabBar;

  @override
  Size get preferredSize => tabBar!.preferredSize;

  @override
  Widget build(BuildContext context) => Container(
        color: color,
        child: tabBar,
      );
}

登录后,他们登陆“探索”屏幕,但想知道这种结构是否理想。我在想的是一个空白主体的“通用”脚手架、5 个 BottomNavigationBarItems 和不断变化的 AppBar 菜单项(例如,“消息传递”具有“对话”和“约会”AppBar 项)

我们如何正确编码。

在此处输入图像描述

这是“消息传递”BottomNavigationBarItem 的示例。

在此处输入图像描述

标签: flutterdartflutter-layout

解决方案


一种可能的方法:

  1. Scaffold你的BottomNavigationBar.
  2. 使用IndexedStack见这里)作为body你的Scaffold.
  3. 创建不同的主体(探索、消息传递等)并setState在用户单击其中一个时使用BottomNavigationBarItems并更改IndexedStack.
  4. 还为不同的主体创建不同AppBar的小部件(例如在数组中),Scaffold根据状态值将其分配给 ,并在前面提到的setState更新中也更新其值。

这将一直有效,直到您可以或想要将所有这些小部件保留在同一个无状态小部件类中。稍后您很有可能希望将它们分成不同的类,以便您的代码更易于阅读。在这种情况下,您可以使用 ChangeNotifier、ChangeNotifierProvider 和 Consumer 在您的小部件之间传达状态更改,如此处所述


推荐阅读