Flutter动画底部导航栏插件animated_notch_bottom_bar的使用

发布于 1周前 作者 htzhanglong 来自 Flutter

Flutter动画底部导航栏插件animated_notch_bottom_bar的使用

Animated Notch Bottom Bar

animated_notch_bottom_bar version Flutter Website Dart Website

Animated Notch Bottom Bar 是一个Flutter插件,用于创建带有凹槽效果的底部导航栏。它允许你通过动画来改变选中项的位置,并且可以自定义凹槽的颜色、大小和其他属性。

Features

  • 支持任何Widget作为底部栏子项
  • 动画化凹槽朝向选定项移动
  • 创建具有美丽动画效果的优化底部导航栏
  • 支持类似iOS Tab View的模糊效果

Getting Started

首先,在pubspec.yaml文件中添加依赖:

dependencies:
  animated_notch_bottom_bar: ^1.0.0

然后在你的Dart代码中导入该包并开始使用它。

Basic Usage

下面是一个完整的示例,展示了如何将AnimatedNotchBottomBar集成到项目中:

import 'dart:developer';

import 'package:animated_notch_bottom_bar/animated_notch_bottom_bar/animated_notch_bottom_bar.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Animated Notch Bottom Bar',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  /// Controller to handle PageView and also handles initial page
  final _pageController = PageController(initialPage: 0);

  /// Controller to handle bottom nav bar and also handles initial page
  final NotchBottomBarController _controller = NotchBottomBarController(index: 0);

  int maxCount = 5;

  @override
  void dispose() {
    _pageController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    /// widget list
    final List<Widget> bottomBarPages = [
      Page1(controller: (_controller)),
      const Page2(),
      const Page3(),
      const Page4(),
      const Page5(),
    ];
    return Scaffold(
      body: PageView(
        controller: _pageController,
        physics: const NeverScrollableScrollPhysics(),
        children: List.generate(bottomBarPages.length, (index) => bottomBarPages[index]),
      ),
      extendBody: true,
      bottomNavigationBar: (bottomBarPages.length <= maxCount)
          ? AnimatedNotchBottomBar(
              notchBottomBarController: _controller,
              color: Colors.white,
              showLabel: true,
              textOverflow: TextOverflow.visible,
              maxLine: 1,
              shadowElevation: 5,
              kBottomRadius: 28.0,
              notchColor: Colors.black87,
              removeMargins: false,
              bottomBarWidth: 500,
              showShadow: false,
              durationInMilliSeconds: 300,
              itemLabelStyle: const TextStyle(fontSize: 10),
              elevation: 1,
              bottomBarItems: const [
                BottomBarItem(
                  inActiveItem: Icon(Icons.home_filled, color: Colors.blueGrey),
                  activeItem: Icon(Icons.home_filled, color: Colors.blueAccent),
                  itemLabel: 'Page 1',
                ),
                BottomBarItem(
                  inActiveItem: Icon(Icons.star, color: Colors.blueGrey),
                  activeItem: Icon(Icons.star, color: Colors.blueAccent),
                  itemLabel: 'Page 2',
                ),
                BottomBarItem(
                  inActiveItem: Icon(Icons.settings, color: Colors.blueGrey),
                  activeItem: Icon(Icons.settings, color: Colors.pink),
                  itemLabel: 'Page 3',
                ),
                BottomBarItem(
                  inActiveItem: Icon(Icons.person, color: Colors.blueGrey),
                  activeItem: Icon(Icons.person, color: Colors.yellow),
                  itemLabel: 'Page 4',
                ),
              ],
              onTap: (index) {
                log('current selected index $index');
                _pageController.jumpToPage(index);
              },
              kIconSize: 24.0,
            )
          : null,
    );
  }
}

/// add controller to check weather index through change or not. in page 1
class Page1 extends StatelessWidget {
  final NotchBottomBarController? controller;

  const Page1({Key? key, this.controller}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.yellow,
      child: Center(
        child: GestureDetector(
          behavior: HitTestBehavior.translucent,
          onTap: () {
            controller?.jumpTo(2);
          },
          child: const Text('Page 1'),
        ),
      ),
    );
  }
}

class Page2 extends StatelessWidget {
  const Page2({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(color: Colors.green, child: const Center(child: Text('Page 2')));
  }
}

class Page3 extends StatelessWidget {
  const Page3({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(color: Colors.red, child: const Center(child: Text('Page 3')));
  }
}

class Page4 extends StatelessWidget {
  const Page4({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(color: Colors.blue, child: const Center(child: Text('Page 4')));
  }
}

class Page5 extends StatelessWidget {
  const Page5({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(color: Colors.lightGreenAccent, child: const Center(child: Text('Page 5')));
  }
}

自定义选项

你可以根据需要调整以下参数来自定义底部导航栏的行为和外观:

  • removeMargins: 移除边距,默认为false
  • bottomBarWidth: 设置底部栏宽度(适用于Web和桌面应用)
  • durationInMilliSeconds: 设置动画持续时间
  • showLabel: 显示或隐藏标签
  • itemLabelStyle: 设置标签样式
  • showShadow: 是否显示阴影
  • showBlurBottomBar: 启用模糊效果
  • blurOpacity, blurFilterX, blurFilterY: 控制模糊效果的具体参数
  • notchColor, notchGradient: 设置凹槽颜色或渐变色
  • showTopRadius, showBottomRadius: 显示或隐藏圆角
  • elevation: 设置底部栏的高度
  • bottomBarHeight: 设置底部栏的高度

更多详细信息请参考官方文档或直接查看源码中的注释。

Migrating to 1.0.0+

从版本1.0.0开始,NotchBottomBarController被引入以控制动画,而不再使用PageController。因此你需要更新你的代码来适应这一变化。

License

本插件遵循MIT许可协议。

如果你有任何问题或建议,请随时联系开发者团队!


更多关于Flutter动画底部导航栏插件animated_notch_bottom_bar的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter动画底部导航栏插件animated_notch_bottom_bar的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter中使用animated_notch_bottom_bar插件来实现带有动画效果的底部导航栏的代码示例。

首先,确保在你的pubspec.yaml文件中添加animated_notch_bottom_bar依赖:

dependencies:
  flutter:
    sdk: flutter
  animated_notch_bottom_bar: ^最新版本号  # 请替换为实际最新版本号

然后,运行flutter pub get来安装依赖。

接下来,在你的Flutter项目中,可以按照以下步骤实现带有动画效果的底部导航栏:

  1. 导入必要的包
import 'package:flutter/material.dart';
import 'package:animated_notch_bottom_bar/animated_notch_bottom_bar.dart';
  1. 定义页面内容

假设你有三个页面,分别为HomePageSearchPageProfilePage,可以简单地用ScaffoldCenter来展示一些内容。

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home')),
      body: Center(child: Text('Home Page')),
    );
  }
}

class SearchPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Search')),
      body: Center(child: Text('Search Page')),
    );
  }
}

class ProfilePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Profile')),
      body: Center(child: Text('Profile Page')),
    );
  }
}
  1. 创建主应用

使用AnimatedNotchBottomBar来创建底部导航栏,并使用IndexedStack来管理页面切换。

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
  int _selectedIndex = 0;

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        body: IndexedStack(
          index: _selectedIndex,
          children: [
            HomePage(),
            SearchPage(),
            ProfilePage(),
          ],
        ),
        bottomNavigationBar: AnimatedNotchBottomBar(
          notchWidth: 24,
          notchHeight: 6,
          notchColor: Colors.white,
          backgroundColor: Colors.blue,
          items: [
            AnimatedNotchBottomBarItem(
              icon: Icon(Icons.home),
              title: 'Home',
              color: Colors.white,
            ),
            AnimatedNotchBottomBarItem(
              icon: Icon(Icons.search),
              title: 'Search',
              color: Colors.white,
            ),
            AnimatedNotchBottomBarItem(
              icon: Icon(Icons.person),
              title: 'Profile',
              color: Colors.white,
            ),
          ],
          currentIndex: _selectedIndex,
          onItemSelected: _onItemTapped,
          animationDuration: 300,
        ),
      ),
    );
  }
}

void main() {
  runApp(MyApp());
}

在这个示例中,我们:

  • 定义了三个简单的页面:HomePageSearchPageProfilePage
  • 在主应用MyApp中,使用IndexedStack来根据_selectedIndex切换页面。
  • 使用AnimatedNotchBottomBar来创建底部导航栏,并设置了图标、标题、颜色等属性。
  • 通过onItemSelected回调来更新_selectedIndex,从而实现页面切换。

运行这个代码,你将看到一个带有动画效果的底部导航栏,能够在不同页面之间切换。

回到顶部