Flutter持久化底部导航栏插件persistent_bottom_nav_bar_v2的使用

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

Flutter持久化底部导航栏插件persistent_bottom_nav_bar_v2的使用

概述

persistent_bottom_nav_bar_v2 是一个高度可定制的Flutter底部导航栏插件,提供17种预设样式,并支持自定义样式。它不仅提供了丰富的功能,还支持透明效果、模糊效果以及硬件/软件返回键处理等功能。

特性

  • 支持17种预设样式。
  • 支持自定义样式。
  • 持久化的标签页,切换时不会丢失导航栈。
  • 支持透明和模糊效果。
  • 处理Android硬件/软件返回键。
  • 支持 go_router 以利用Flutter的Router API。

安装与使用

1. 安装包

pubspec.yaml 文件中添加依赖:

dependencies:
  persistent_bottom_nav_bar_v2: ^latest_version

然后运行 flutter pub get

2. 导入包

在Dart文件中导入包:

import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart';

3. 使用 PersistentTabView

PersistentTabView 是你的顶级容器,用于包含导航栏和所有页面。以下是基本用法:

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

void main() => runApp(PersistenBottomNavBarDemo());

class PersistenBottomNavBarDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Persistent Bottom Navigation Bar Demo',
      home: PersistentTabView(
        tabs: [
          PersistentTabConfig(
            screen: YourFirstScreen(),
            item: ItemConfig(
              icon: Icon(Icons.home),
              title: "Home",
            ),
          ),
          PersistentTabConfig(
            screen: YourSecondScreen(),
            item: ItemConfig(
              icon: Icon(Icons.message),
              title: "Messages",
            ),
          ),
          PersistentTabConfig(
            screen: YourThirdScreen(),
            item: ItemConfig(
              icon: Icon(Icons.settings),
              title: "Settings",
            ),
          ),
        ],
        navBarBuilder: (navBarConfig) => Style1BottomNavBar(
          navBarConfig: navBarConfig,
        ),
      ),
    );
  }
}

自定义样式

你可以通过传递 NavBarDecoration 来自定义导航栏的样式。例如,设置不同的圆角半径:

navBarDecoration: NavBarDecoration(borderRadius: BorderRadius.circular(8))

使用自定义导航栏

你还可以创建自己的导航栏组件:

class CustomNavBar extends StatelessWidget {
  final NavBarConfig navBarConfig;
  final NavBarDecoration navBarDecoration;

  const CustomNavBar({
    super.key,
    required this.navBarConfig,
    this.navBarDecoration = const NavBarDecoration(),
  });

  Widget _buildItem(ItemConfig item, bool isSelected) {
    final title = item.title;
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Expanded(
          child: IconTheme(
            data: IconThemeData(
              size: item.iconSize,
              color: isSelected
                  ? item.activeForegroundColor
                  : item.inactiveForegroundColor,
            ),
            child: isSelected ? item.icon : item.inactiveIcon,
          ),
        ),
        if (title != null)
          Padding(
            padding: const EdgeInsets.only(top: 15.0),
            child: Material(
              type: MaterialType.transparency,
              child: FittedBox(
                child: Text(
                  title,
                  style: item.textStyle.apply(
                    color: isSelected
                        ? item.activeForegroundColor
                        : item.inactiveForegroundColor,
                  ),
                ),
              ),
            ),
          ),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return DecoratedNavBar(
      decoration: navBarDecoration,
      height: navBarConfig.navBarHeight,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          for (final (index, item) in navBarConfig.items.indexed)
            Expanded(
              child: InkWell(
                onTap: () => navBarConfig.onItemSelected(index),
                child: _buildItem(item, navBarConfig.selectedIndex == index),
              ),
            ),
        ],
      ),
    );
  }
}

程序控制导航栏

通过 PersistentTabController 控制导航栏:

PersistentTabController _controller = PersistentTabController(initialIndex: 0);

PersistentTabView(
  controller: _controller,
  ...
);

_controller.jumpToTab(2);
// 返回到上一个标签页
_controller.jumpToPreviousTab();

自定义页面切换动画

通过 animatedTabBuilder 自定义页面切换动画:

PersistentTabView(
  animatedTabBuilder: (context, index, animationValue, newIndex, oldIndex, child) {
    final double yOffset = newIndex > index
        ? -animationValue
        : (newIndex < index
            ? animationValue
            : (index < oldIndex ? animationValue - 1 : 1 - animationValue));
    return FractionalTranslation(
      translation: Offset(yOffset, 0),
      child: child,
    );
  },
  ...
);

导航

每个标签页都有独立的导航器,可以避免相互干扰。使用 pushScreen 方法来控制是否显示导航栏:

pushScreen(
  context,
  screen: MainScreen(),
  withNavBar: true,
);

路由API集成

结合 go_router 使用路由API:

StatefulShellRoute.indexedStack(
  builder: (context, state, navigationShell) =>
      PersistentTabView.router(
    tabs: [
      PersistentRouterTabConfig(
        item: ItemConfig(
          icon: const Icon(Icons.home),
          title: "Home",
        ),
      ),
      // 其他标签配置...
    ],
    navBarBuilder: (navBarConfig) => Style1BottomNavBar(
      navBarConfig: navBarConfig,
    ),
    navigationShell: navigationShell,
  ),
  branches: [
    StatefulShellBranch(
      routes: <RouteBase>[
        GoRoute(
          path: "home",
          builder: (context, state) => const MainScreen(
            useRouter: true,
          ),
          routes: [
            GoRoute(
              path: "detail",
              builder: (context, state) => const MainScreen2(
                useRouter: true,
              ),
            ),
          ],
        ),
      ],
    ),
    // 其他分支配置...
  ],
),

实用提示

  • 尝试官方Git仓库中的交互示例项目。
  • 使用 Navigator.of(context).popUntil 返回到指定屏幕。
  • 使用 badges 包为图标添加通知计数。

示例代码

以下是一个简单的示例代码,展示了如何使用 persistent_bottom_nav_bar_v2

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

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setSystemUIOverlayStyle(
    const SystemUiOverlayStyle(
      systemNavigationBarColor: Colors.transparent,
    ),
  );
  SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
  runApp(const PersistenBottomNavBarDemo());
}

class PersistenBottomNavBarDemo extends StatelessWidget {
  const PersistenBottomNavBarDemo({super.key});

  @override
  Widget build(BuildContext context) => MaterialApp(
        title: "Persistent Bottom Navigation Bar Demo",
        home: Builder(
          builder: (context) => Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                ElevatedButton(
                  onPressed: () => Navigator.of(context).pushNamed("/minimal"),
                  child: const Text("Show Minimal Example"),
                ),
                const SizedBox(height: 16),
                ElevatedButton(
                  onPressed: () => Navigator.of(context).pushNamed("/interactive"),
                  child: const Text("Show Interactive Example"),
                ),
              ],
            ),
          ),
        ),
        routes: {
          "/minimal": (context) => const MinimalExample(),
          "/interactive": (context) => const InteractiveExample(),
        },
      );
}

class MinimalExample extends StatelessWidget {
  const MinimalExample({super.key});

  List<PersistentTabConfig> _tabs() => [
        PersistentTabConfig(
          screen: const MainScreen(),
          item: ItemConfig(
            activeForegroundColor: Colors.white,
            inactiveBackgroundColor: Colors.white,
            icon: const Icon(Icons.home),
            title: "Home",
          ),
        ),
        PersistentTabConfig(
          screen: const MainScreen(),
          item: ItemConfig(
            icon: const Icon(Icons.message),
            title: "Messages",
          ),
        ),
        PersistentTabConfig(
          screen: const MainScreen(),
          item: ItemConfig(
            icon: const Icon(Icons.settings),
            title: "Settings",
          ),
        ),
      ];

  @override
  Widget build(BuildContext context) => PersistentTabView(
        backgroundColor: Colors.red,
        tabs: _tabs(),
        navBarBuilder: (navBarConfig) => Style1BottomNavBar(
          navBarConfig: navBarConfig,
          navBarDecoration: NavBarDecoration(color: Colors.transparent),
        ),
        navBarOverlap: NavBarOverlap.full(),
      );
}

希望这些信息能帮助你更好地理解和使用 persistent_bottom_nav_bar_v2 插件!如果有任何问题,请随时提问。


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

1 回复

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


当然,以下是如何在Flutter应用中使用persistent_bottom_nav_bar_v2插件来实现持久化底部导航栏的示例代码。这个插件可以帮助你轻松地管理底部导航栏的状态,并在页面重建时保持其状态。

首先,确保你已经在pubspec.yaml文件中添加了persistent_bottom_nav_bar_v2依赖:

dependencies:
  flutter:
    sdk: flutter
  persistent_bottom_nav_bar_v2: ^x.y.z  # 请替换为最新版本号

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

接下来,你可以按照以下步骤在你的Flutter应用中使用该插件:

  1. 导入必要的包
import 'package:flutter/material.dart';
import 'package:persistent_bottom_nav_bar_v2/persistent-tab-view.dart';
  1. 定义你的导航项和页面
List<PersistentBottomNavBarItem> _navBarsItems = [
  PersistentBottomNavBarItem(
    icon: Icon(Icons.home),
    title: ("Home"),
  ),
  PersistentBottomNavBarItem(
    icon: Icon(Icons.search),
    title: ("Search"),
  ),
  PersistentBottomNavBarItem(
    icon: Icon(Icons.library_books),
    title: ("Library"),
  ),
  PersistentBottomNavBarItem(
    icon: Icon(Icons.person),
    title: ("Profile"),
  ),
];

List<Widget> _screenPages = [
  HomeScreen(),
  SearchScreen(),
  LibraryScreen(),
  ProfileScreen(),
];
  1. 创建你的主页面
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Persistent Bottom Nav Bar Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: PersistentTabView(
        context,
        _screenPages,
        _navBarsItems,
        initialIndex: 0, // 初始选中的导航项索引
        backgroundColor: Colors.white,
        handleSelected: (index) {
          // 可以在这里处理导航项选中的逻辑
          print('Selected index: $index');
        },
        confineInSafeArea: true,
        decoration: NavBarDecoration(
          borderRadius: BorderRadius.circular(10.0),
          colorBehindNavBar: Colors.white,
        ),
        popActionScreens: PopActionScreensType.all,
        itemAnimationProperties: ItemAnimationProperties(
          duration: Duration(milliseconds: 200),
          curve: Curves.ease,
        ),
        screenTransitionAnimation: ScreenTransitionAnimation(
          animateTabTransition: true,
          curve: Curves.ease,
          duration: Duration(milliseconds: 250),
        ),
        navBarStyle: NavBarStyle.style12,
      ),
    );
  }
}
  1. 定义你的页面

例如,HomeScreen可以是一个简单的Scaffold

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

// 其他屏幕(SearchScreen, LibraryScreen, ProfileScreen)可以类似定义
  1. 运行你的应用

确保你的main.dart文件使用了MyApp作为根组件:

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

这样,你就成功地在Flutter应用中使用persistent_bottom_nav_bar_v2插件实现了持久化底部导航栏。这个插件会帮助你在页面重建时保持导航栏的状态,从而提供更好的用户体验。

回到顶部