Flutter自定义顶部导航插件custom_top_navigator的使用

Flutter自定义顶部导航插件custom_top_navigator的使用

一个用于创建任意位置自定义导航器的Flutter插件。

常用于实现始终显示的底部导航栏。

开始使用

首先,你需要在pubspec.yaml文件中添加该包。

自定义支架(Custom Scaffold)

CustomScaffold是一个状态化的widget,它使用CustomTopNavigator来处理带有嵌套导航的底部导航栏项目切换,同时保持底部导航栏可见!

使用方法

// 这是自定义支架小部件
// 它接受一个包含必填底部导航栏的正常支架
// 和作为子页面的小部件
CustomScaffold(
      scaffold: Scaffold(
        bottomNavigationBar: BottomNavigationBar(
          items: _items,
        ),
      ),

      // 子页面是在每次点击时将要显示的页面
      // 它们应该按顺序放置,例如
      // 点击`item 0`在底部导航栏时,将显示`page 0`
      children: [
        Page('0'),
        Page('1'),
        Page('2'),
      ],

      // 当点击其中一个`items`时调用。
      onItemTap: (index) {},
    );

更多详细信息请参阅 custom_scaffold_example


自定义顶部导航器(Custom Top Navigator)

CustomTopNavigator使用起来非常简单。

使用方法

CustomTopNavigator(
        home: YourChildWidget(),
        // 指定你的页面路由 [PageRoutes.materialPageRoute] 或 [PageRoutes.cupertinoPageRoute]
        pageRoute: PageRoutes.materialPageRoute,
      );

然后你可以像以前一样使用 Navigator.of(context) 来调用它。

选项

  • 你可以指定命名路由,就像在MaterialApp中一样。
  • 如果你想使用默认的Navigator,则需要为MaterialApp指定一个GlobalKey并在需要的地方使用它navigatorKey.currentState

更多详细信息请参阅 example

示例代码

以下是完整的示例代码:

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

void main() => runApp(const MyApp());

// 如果你想在应用的任何地方使用默认导航器,
// 给 [MaterialApp] 提供一个 navigator key,例如第15行和第93行
GlobalKey<NavigatorState> mainNavigatorKey = GlobalKey<NavigatorState>();

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

  // 这个widget是你的应用的根
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorKey: mainNavigatorKey,
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

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

  final String title;

  [@override](/user/override)
  MyHomePageState createState() => MyHomePageState();
}

class MyHomePageState extends State<MyHomePage> {
  Page _page =  const Page('Page 0');
  int _currentIndex = 0;

  // Custom navigator 需要一个 global key 如果你想从它的 widget 树以外的地方访问导航器
  GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      bottomNavigationBar: BottomNavigationBar(
        items: _items,
        onTap: (index) {
          // 在这里我们使用 navigator key 来弹出堆栈回到我们的主页面
          navigatorKey.currentState?.maybePop();
          setState(() => _page = Page('Page $index'));
          _currentIndex = index;
        },
        currentIndex: _currentIndex,
      ),
      body: CustomTopNavigator(
        navigatorKey: navigatorKey,
        home: _page,
        // 指定你的页面路由 [PageRoutes.materialPageRoute] 或 [PageRoutes.cupertinoPageRoute]
        pageRoute: PageRoutes.materialPageRoute,
      ),
    );
  }

  final _items = [
    const BottomNavigationBarItem(icon: Icon(Icons.home), label: 'home'),
    const BottomNavigationBarItem(icon: Icon(Icons.event), label: 'events'),
    const BottomNavigationBarItem(
        icon: Icon(Icons.save_alt), label: 'downloads'),
  ];
}

class Page extends StatelessWidget {
  final String title;

  const Page(this.title, {Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    final text = Text(title);

    return Center(
        child: TextButton(
            onPressed: () => _openDetailsPage(context), child: text));
  }

  // 使用你通常使用的 .of(context) 方法调用导航器
  _openDetailsPage(BuildContext context) =>
      Navigator.of(context)
          .push(MaterialPageRoute(builder: (context) => DetailsPage(title)));

//  _openDetailsPage(BuildContext context) =>
//       mainNavigatorKey.currentState.push(MaterialPageRoute(builder: (context) => DetailsPage(title)));
}

class DetailsPage extends StatelessWidget {
  final String title;

  const DetailsPage(this.title, {Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    final text = Text('Details of $title');
    return Center(child: text);
  }
}

更多关于Flutter自定义顶部导航插件custom_top_navigator的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter自定义顶部导航插件custom_top_navigator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,你可以通过自定义Widget来实现一个顶部导航栏。虽然Flutter本身提供了AppBar组件,但如果你需要更复杂的功能或自定义样式,可以创建一个自定义的顶部导航栏插件。下面是一个简单的示例,展示如何创建一个自定义的顶部导航栏插件,并如何使用它。

1. 创建自定义顶部导航栏插件

首先,创建一个名为custom_top_navigator.dart的文件,并在其中定义你的自定义顶部导航栏组件。

import 'package:flutter/material.dart';

class CustomTopNavigator extends StatelessWidget {
  final List<String> tabTitles;
  final int selectedIndex;
  final Function(int) onTabChanged;

  CustomTopNavigator({
    required this.tabTitles,
    required this.selectedIndex,
    required this.onTabChanged,
  });

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Container(
      height: 50.0,
      color: Colors.blue,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: List.generate(tabTitles.length, (index) {
          return GestureDetector(
            onTap: () => onTabChanged(index),
            child: Container(
              alignment: Alignment.center,
              padding: EdgeInsets.symmetric(horizontal: 20.0),
              decoration: BoxDecoration(
                border: Border(
                  bottom: BorderSide(
                    color: selectedIndex == index ? Colors.white : Colors.transparent,
                    width: 2.0,
                  ),
                ),
              ),
              child: Text(
                tabTitles[index],
                style: TextStyle(
                  color: selectedIndex == index ? Colors.white : Colors.white70,
                  fontSize: 16.0,
                  fontWeight: FontWeight.bold,
                ),
              ),
            ),
          );
        }),
      ),
    );
  }
}

2. 在应用中使用自定义顶部导航栏

接下来,在你的主应用中使用这个自定义顶部导航栏。假设你的主应用文件是main.dart,你可以在其中使用CustomTopNavigator

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

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  [@override](/user/override)
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  int _selectedIndex = 0;

  final List<String> _tabTitles = ['Home', 'Profile', 'Settings'];

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Custom Top Navigator'),
      ),
      body: Column(
        children: [
          CustomTopNavigator(
            tabTitles: _tabTitles,
            selectedIndex: _selectedIndex,
            onTabChanged: _onTabChanged,
          ),
          Expanded(
            child: Center(
              child: Text('Selected Tab: ${_tabTitles[_selectedIndex]}'),
            ),
          ),
        ],
      ),
    );
  }
}
回到顶部