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
更多关于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]}'),
),
),
],
),
);
}
}