Flutter响应式导航栏插件responsive_navbar的使用

Flutter响应式导航栏插件responsive_navbar的使用

该插件提供了带有动画和高度自定义功能的导航栏。它支持全屏移动设备和桌面设备。

全屏移动设备支持

全屏桌面设备支持

使用方法

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

dependencies:
  flutter:
    sdk: flutter
  responsive_navbar: ^x.x.x

接下来,你可以使用以下代码来实现响应式导航栏:

[@override](/user/override)
Widget build(BuildContext context) {
  return Container(
      child: ResponsiveBar(
          barCircularity: 0,
          iconPadding: EdgeInsets.only(bottom: 5, top: 5),
          barThickness: 5,
          usingRightBar: true,
          isForDesktop: true,
          currentIndex: currentIndex,
          onTap: _handleIndexChanged(),
          iconSize: 35,
          scaling: 60,
          iconScaleAnimationFactor: 0.3,
          iconScaleCurve: Curves.decelerate,
          barSizeCurve: Curves.decelerate,
          barAccentColor: FlutterFlowTheme.primaryColor,
          backgroundColor: HexColor("#060606"),
          activeItemColor: HexColor("#F1F1F1"),
          passiveItemColor: HexColor("#444444"),
          items: [
            ResponsiveBarItem(
                icon: Icon(Icons.store_outlined),
                selectedIcon: Icon(Icons.store_rounded)),
            ResponsiveBarItem(
                icon: Icon(Icons.badge_outlined),
                selectedIcon: Icon(Icons.badge_rounded)),
            ResponsiveBarItem(
                icon: Icon(Icons.vpn_key_outlined),
                selectedIcon: Icon(Icons.vpn_key_rounded)),
            ResponsiveBarItem(
                icon: Icon(Icons.source_outlined),
                selectedIcon: Icon(Icons.source_rounded)),
            ResponsiveBarItem(
                icon: Icon(Icons.linear_scale_outlined),
                selectedIcon: Icon(Icons.linear_scale_rounded))
          ]
      )
  );
}

完整示例Demo

下面是一个完整的示例代码,展示了如何在Flutter应用中使用 responsive_navbar 插件。

// ignore_for_file: must_be_immutable

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

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: DesktopMain(title: 'Flutter Demo Home Page'),
    );
  }
}

class DesktopMain extends StatefulWidget {
  DesktopMain({super.key, required this.title, this.index = 0});

  final String title;

  late int index;

  [@override](/user/override)
  State<DesktopMain> createState() => _DesktopMainState();
}

class _DesktopMainState extends State<DesktopMain> {
  final ValueNotifier<int> _currentIndex = ValueNotifier(0);
  late PageController pageController;

  [@override](/user/override)
  void initState() {
    super.initState();
    pageController = PageController(initialPage: widget.index);
    _currentIndex.value = widget.index;
  }

  [@override](/user/override)
  void dispose() {
    super.dispose();
    pageController.dispose();
  }

  void _handleIndexChanged(int index) {
    if (_currentIndex.value != index) {
      pageController
          .jumpToPage(_currentIndex.value < index ? index - 1 : index + 1);
      pageController.animateToPage(index,
          duration: const Duration(milliseconds: 700),
          curve: Curves.easeInOutQuart);
      _currentIndex.value = index;
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        color: const Color(0xFF131313),
        child: Row(
          children: [
            ValueListenableBuilder(
              valueListenable: _currentIndex,
              builder: (context, dynamic currentIndex, _) => ResponsiveBar(
                useIconScaleCurve: true,
                barCircularity: 0,
                iconPadding: const EdgeInsets.only(bottom: 25, top: 25),
                barThickness: 5,
                isForDesktop: true,
                currentIndex: currentIndex,
                onTap: (index) => _handleIndexChanged(index),
                iconSize: 35,
                scaling: 60,
                iconScaleAnimationFactor: 0.5,
                iconScaleCurve: Curves.decelerate,
                barSizeCurve: Curves.decelerate,
                barAccentColor: Colors.white,
                backgroundColor: Colors.black45,
                activeItemColor: Colors.white,
                passiveItemColor: Colors.white30,

                transition: const Duration(milliseconds: 400),
                itemsStaked: true,
                usingItemDescription: true,
                tooltipStayDuration: const Duration(milliseconds: 500),
                items: [
                  ResponsiveBarItem(
                      description: "test",
                      icon: const Icon(Icons.store_outlined),
                      selectedIcon: const Icon(Icons.store_rounded)),
                  ResponsiveBarItem(
                      description: "test2",
                      icon: const Icon(Icons.badge_outlined),
                      selectedIcon: const Icon(Icons.badge_rounded)),
                  ResponsiveBarItem(
                      description: "test3",
                      icon: const Icon(Icons.vpn_key_outlined),
                      selectedIcon: const Icon(Icons.vpn_key_rounded)),
                  ResponsiveBarItem(
                      description: "test4",
                      icon: const Icon(Icons.source_outlined),
                      selectedIcon: const Icon(Icons.source_rounded)),
                  ResponsiveBarItem(
                      description: "test5",
                      icon: const Icon(Icons.linear_scale_outlined),
                      selectedIcon: const Icon(Icons.linear_scale_rounded))
                ],
              ),
            ),
            Expanded(
              child: PageView(
                physics: const NeverScrollableScrollPhysics(),
                scrollDirection: Axis.vertical,
                controller: pageController,
                onPageChanged: (index) => _currentIndex.value = index,
                children: const <Widget>[
                  Placeholder(),
                  Placeholder(),
                  Placeholder(),
                  Placeholder(),
                  Placeholder(),
                ],
              ),
            )
          ],
        ),
      ),
    );
  }
}

class MobileMain extends StatefulWidget {
  MobileMain({super.key, required this.title, this.index = 0});

  final String title;
  int index = 0;

  [@override](/user/override)
  State<MobileMain> createState() => _MobileMainState();
}

class _MobileMainState extends State<MobileMain> {
  final ValueNotifier<int> _currentIndex = ValueNotifier(0);
  late PageController pageController;

  [@override](/user/override)
  void initState() {
    super.initState();
    pageController = PageController(initialPage: widget.index);
    _currentIndex.value = widget.index;
  }

  [@override](/user/override)
  void dispose() {
    super.dispose();
    pageController.dispose();
  }

  void _handleIndexChanged(int index) {
    if (_currentIndex.value != index) {
      pageController
          .jumpToPage(_currentIndex.value < index ? index - 1 : index + 1);
      pageController.animateToPage(index,
          duration: const Duration(milliseconds: 700),
          curve: Curves.easeInOutQuart);
      _currentIndex.value = index;
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
        body: Container(
      color: const Color(0xFF131313),
      child: Column(
        children: [
          Expanded(
            //################################################################
            //PageView
            //################################################################
            child: PageView(
              physics: const NeverScrollableScrollPhysics(),
              scrollDirection: Axis.vertical,
              controller: pageController,
              onPageChanged: (index) => _currentIndex.value = index,
              children: const <Widget>[
                Placeholder(),
                Placeholder(),
                Placeholder(),
                Placeholder(),
                Placeholder(),
              ],
            ),
          ),
          ValueListenableBuilder(
            valueListenable: _currentIndex,
            builder: (context, dynamic currentIndex, _) => ResponsiveBar(
              useBarAnimation: true,
              iconPadding: const EdgeInsets.all(13),
              usingTopBar: true,
              isForDesktop: false,
              currentIndex: currentIndex,
              onTap: _handleIndexChanged,
              iconSize: 30,
              scaling: 60,
              transition: const Duration(milliseconds: 500),
              iconScaleAnimationFactor: 0.5,
              iconScaleCurve: Curves.easeOutSine,
              barSizeCurve: Curves.decelerate,
              barAccentColor: Colors.white,
              backgroundColor: Colors.black38,
              activeItemColor: Colors.white,
              passiveItemColor: Colors.white38,
              items: [
                //######################################################
                //BarItems
                //######################################################
                ResponsiveBarItem(
                    icon: const Icon(Icons.store_outlined),
                    selectedIcon: const Icon(Icons.store_rounded)),
                ResponsiveBarItem(
                    icon: const Icon(Icons.badge_outlined),
                    selectedIcon: const Icon(Icons.badge_rounded)),
                ResponsiveBarItem(
                    icon: const Icon(Icons.vpn_key_outlined),
                    selectedIcon: const Icon(Icons.vpn_key_rounded)),
                ResponsiveBarItem(
                    icon: const Icon(Icons.source_outlined),
                    selectedIcon: const Icon(Icons.source_rounded)),
                ResponsiveBarItem(
                    icon: const Icon(Icons.linear_scale_outlined),
                    selectedIcon: const Icon(Icons.linear_scale_rounded))
              ],
            ),
          ),
        ],
      ),
    ));
  }
}

更多关于Flutter响应式导航栏插件responsive_navbar的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

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


responsive_navbar 是一个用于 Flutter 的响应式导航栏插件,它可以帮助你在不同屏幕尺寸下创建适应性的导航栏。这个插件通常用于在移动设备和桌面设备上显示不同的导航布局,例如在移动设备上显示汉堡菜单,而在桌面设备上显示水平导航栏。

以下是如何使用 responsive_navbar 插件的基本步骤:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 responsive_navbar 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  responsive_navbar: ^0.0.1  # 请检查最新版本

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

2. 导入包

在你的 Dart 文件中导入 responsive_navbar 包:

import 'package:responsive_navbar/responsive_navbar.dart';

3. 使用 ResponsiveNavbar

在你的应用程序中使用 ResponsiveNavbar 组件。你可以根据需要自定义导航栏的外观和行为。

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: ResponsiveNavbar(
        title: Text('My App'),
        items: [
          NavbarItem(
            title: 'Home',
            onTap: () {
              // 处理点击事件
            },
          ),
          NavbarItem(
            title: 'About',
            onTap: () {
              // 处理点击事件
            },
          ),
          NavbarItem(
            title: 'Contact',
            onTap: () {
              // 处理点击事件
            },
          ),
        ],
      ),
      body: Center(
        child: Text('Hello, World!'),
      ),
    );
  }
}

4. 自定义导航栏

你可以通过传递不同的参数来自定义 ResponsiveNavbar 的外观和行为。例如,你可以设置导航栏的背景颜色、文本样式、图标等。

ResponsiveNavbar(
  title: Text('My App'),
  backgroundColor: Colors.blue,
  textStyle: TextStyle(color: Colors.white),
  items: [
    NavbarItem(
      title: 'Home',
      icon: Icon(Icons.home),
      onTap: () {
        // 处理点击事件
      },
    ),
    NavbarItem(
      title: 'About',
      icon: Icon(Icons.info),
      onTap: () {
        // 处理点击事件
      },
    ),
    NavbarItem(
      title: 'Contact',
      icon: Icon(Icons.contact_mail),
      onTap: () {
        // 处理点击事件
      },
    ),
  ],
)

5. 处理响应式布局

responsive_navbar 插件会自动处理不同屏幕尺寸的布局。在较小的屏幕上,导航栏会显示为汉堡菜单,而在较大的屏幕上,导航栏会显示为水平布局。

6. 运行应用

最后,运行你的 Flutter 应用程序,看看 responsive_navbar 如何在不同的设备上工作。

flutter run
回到顶部