【问题标题】:flutter: how to create bottom navigation bar like this颤振:如何创建这样的底部导航栏
【发布时间】:2021-10-11 21:20:12
【问题描述】:

我想制作一个与照片中完全一样的底部导航栏,但我做不到。 请帮帮我。

我还想在每个部分之间划分部分。请帮帮我

【问题讨论】:

标签: flutter flutter-layout flutter-dependencies flutter-animation flutter-test


【解决方案1】:

您可以使用BottomAppBar 自定义创建bottomNavigationBar

例子:

第 1 步:在此示例中创建一个有状态的小部件,其名称为 MyHomePage

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _selectedIndex = 0;

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      //Default is true so this can be ignore/removed
      resizeToAvoidBottomInset: true,
      appBar: AppBar(
        title: Text(widget.title),
      ),
      bottomNavigationBar: BottomAppBar(
        child: Container(
          height: 56,
          padding: EdgeInsets.all(6),
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              BottomNavigationMenu(
                label: 'Home',
                isSelected: _selectedIndex == 0,
                icon: Icons.home,
                onTap: () {
                  _onItemTapped(0);
                },
              ),
              VerticalDivider(),
              BottomNavigationMenu(
                label: 'Business',
                isSelected: _selectedIndex == 1,
                icon: Icons.work,
                onTap: () {
                  _onItemTapped(1);
                },
              ),
              VerticalDivider(),
              BottomNavigationMenu(
                label: 'Map',
                isSelected: _selectedIndex == 2,
                icon: Icons.map_outlined,
                onTap: () {
                  _onItemTapped(2);
                },
              ),
              VerticalDivider(),
              BottomNavigationMenu(
                label: 'Service',
                isSelected: _selectedIndex == 3,
                icon: Icons.room_service,
                onTap: () {
                  _onItemTapped(3);
                },
              ),
              VerticalDivider(),
              BottomNavigationMenu(
                label: 'Profile',
                isSelected: _selectedIndex == 4,
                icon: Icons.account_circle,
                onTap: () {
                  _onItemTapped(4);
                },
              ),
            ],
          ),
        ),
      ),
      body: SingleChildScrollView(
        padding: EdgeInsets.all(16),
        child: Center(
          child: Text("Demo"),
        ),
      ),
    );
  }
}

第 2 步:使用 StatelessWidget 即创建自定义的 BottomNavigationMenu 项。 BottomNavigationMenu:

class BottomNavigationMenu extends StatelessWidget {
  final Function()? onTap;
  final String label;
  final IconData icon;
  final bool isSelected;
  final Color selectedColor = Colors.green;
  final Color defaultColor = Colors.grey;

  const BottomNavigationMenu(
      {required this.icon,
      required this.label,
      required this.onTap,
      required this.isSelected});

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: InkWell(
        onTap: onTap,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Icon(
              icon,
              color: isSelected ? selectedColor : defaultColor,
            ),
            Text(
              label,
              style: Theme.of(context).textTheme.bodyText2!.copyWith(
                    color: isSelected ? selectedColor : defaultColor,
                  ),
            )
          ],
        ),
      ),
    );
  }
}

就是这样。您可以在BottomNavigationMenu 中自定义您选择的颜色。

这就是它的外观:Custom BottomNavigationBar

【讨论】:

    【解决方案2】:

    结果

    CustomNavBarItem

    class BottomNavIcon extends StatelessWidget {
      final IconData iconData;
      final bool isSelected;
      final String label;
    
      final Function callback;
    
      const BottomNavIcon({
        Key? key,
        required this.iconData,
        required this.isSelected,
        required this.label,
        required this.callback,
      }) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTap: () {
            callback();
          },
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Container(
                padding: EdgeInsets.all(8),
                decoration: BoxDecoration(
                  color: isSelected ? Colors.green.shade200 : Colors.grey.shade300,
                  shape: BoxShape.circle,
                ),
                child: Icon(
                  iconData,
                  color: isSelected ? Colors.green.shade800 : Colors.grey.shade600,
                ),
              ),
              Text(
                label,
                style: TextStyle(
                  fontSize: 12,
                  color: isSelected ? Colors.green : Colors.grey,
                  fontWeight: FontWeight.bold,
                ),
              )
            ],
          ),
        );
      }
    }
    
    

    垂直分隔线控件

     get divider => VerticalDivider(
            color: Colors.grey.shade300,
            endIndent: 4,
            indent: 4,
          );
    

    完整的小部件:

    import 'package:flutter/material.dart';
    
    class BottomNavBar extends StatefulWidget {
      BottomNavBar({Key? key}) : super(key: key);
    
      @override
      _BottomNavBarState createState() => _BottomNavBarState();
    }
    
    class _BottomNavBarState extends State<BottomNavBar> {
      int _selectedIndex = 0;
    
      get divider => VerticalDivider(
            color: Colors.grey.shade300,
            endIndent: 4,
            indent: 4,
          );
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Text("Body"),
          bottomNavigationBar: BottomAppBar(
            child: Container(
              //* for padding
              height: kBottomNavigationBarHeight + 16,
              padding: EdgeInsets.all(8),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: [
                  BottomNavIcon(
                    iconData: Icons.home_filled,
                    isSelected: _selectedIndex == 0,
                    label: "Home".toUpperCase(),
                    callback: () {
                      setState(() {
                        _selectedIndex = 0;
                      });
                    },
                  ),
                  divider,
                  BottomNavIcon(
                    iconData: Icons.business_center,
                    isSelected: _selectedIndex == 1,
                    label: "Business".toUpperCase(),
                    callback: () {
                      setState(() {
                        _selectedIndex = 1;
                      });
                    },
                  ),
                  divider,
                  BottomNavIcon(
                    iconData: Icons.location_on_outlined,
                    isSelected: _selectedIndex == 2,
                    label: "Map".toUpperCase(),
                    callback: () {
                      setState(() {
                        _selectedIndex = 2;
                      });
                    },
                  ),
                  divider,
                  BottomNavIcon(
                    iconData: Icons.design_services_outlined,
                    isSelected: _selectedIndex == 3,
                    label: "services".toUpperCase(),
                    callback: () {
                      setState(() {
                        _selectedIndex = 3;
                      });
                    },
                  ),
                  divider,
                  Container(
                    child: BottomNavIcon(
                      iconData: Icons.settings,
                      isSelected: _selectedIndex == 4,
                      label: "Profile".toUpperCase(),
                      callback: () {
                        print("oncalleck  $_selectedIndex");
                        setState(() {
                          _selectedIndex = 4;
                        });
                      },
                    ),
                  ),
                ],
              ),
            ),
          ),
        );
      }
    }
    
    

    【讨论】:

      猜你喜欢
      • 2019-12-03
      • 2017-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多