Flutter标签页导航插件built_tab_navigator的使用
Flutter标签页导航插件built_tab_navigator的使用
built_tab_navigator
插件用于创建具有导航功能的标签页UI。
此插件旨在与 built_value
和 built_collection
一起使用,因为某些API属性期望使用 EnumClass
对象。
安装
在 pubspec.yaml
文件的 dependencies:
部分添加以下行:
dependencies:
built_tab_navigator: <最新版本>
使用
导入此类
import 'package:built_tab_navigator/built_tab_navigator.dart';
默认标签页
BuiltTabNavigator(
tabs: {
ExampleTabs.example1: TabRoutesDefinition(
initialRoute: Example1Routes.root,
routes: example1Routes,
tabTitle: "Example 1",
tabIcon: Icons.ac_unit,
),
ExampleTabs.example2: TabRoutesDefinition(
initialRoute: Example2Routes.root,
routes: example2Routes,
tabTitle: "Example 2",
tabIcon: Icons.accessibility_new,
),
ExampleTabs.example3: TabRoutesDefinition(
initialRoute: Example2Routes.root,
routes: example3Routes,
tabTitle: "Example 3",
tabIcon: Icons.adb,
),
},
)
尝试自定义构建器
BuiltTabNavigator(
iconBuilder: (context, tab, definition, selected) {
return Container(
padding: EdgeInsets.all(4),
decoration: BoxDecoration(
color: Colors.purple,
borderRadius: BorderRadius.circular(20),
),
child: Icon(definition.tabIcon, color: selected ? Colors.white : Colors.black,),
);
},
titleBuilder: (context, tab, definition, selected) {
return Text(definition.tabTitle, style: TextStyle(fontSize: 20, color: selected ? Colors.purple : Colors.grey),);
},
tabs: {
ExampleTabs.example1: TabRoutesDefinition(
initialRoute: Example1Routes.root,
routes: example1Routes,
tabTitle: "Example 1",
tabIcon: Icons.ac_unit,
),
ExampleTabs.example2: TabRoutesDefinition(
initialRoute: Example2Routes.root,
routes: example2Routes,
tabTitle: "Example 2",
tabIcon: Icons.accessibility_new,
),
ExampleTabs.example3: TabRoutesDefinition(
initialRoute: Example2Routes.root,
routes: example3Routes,
tabTitle: "Example 3",
tabIcon: Icons.adb,
),
},
)
更改布局非常简单
BuiltTabNavigator(
activeTabColor: Colors.red,
inactiveTabColor: Colors.white,
bodyBuilder: (context, tabs, tabView) {
return Column(
children: <Widget>[
Material(
elevation: 9,
color: Colors.blue[200],
child: Container(
height: 100,
child: Row(
children: tabs,
),
),
),
Expanded(
child: tabView,
),
],
);
},
tabs: {
ExampleTabs.example1: TabRoutesDefinition(
initialRoute: Example1Routes.root,
routes: example1Routes,
tabTitle: "Example 1",
tabIcon: Icons.ac_unit,
),
ExampleTabs.example2: TabRoutesDefinition(
initialRoute: Example2Routes.root,
routes: example2Routes,
tabTitle: "Example 2",
tabIcon: Icons.accessibility_new,
),
ExampleTabs.example3: TabRoutesDefinition(
initialRoute: Example2Routes.root,
routes: example3Routes,
tabTitle: "Example 3",
tabIcon: Icons.adb,
),
},
)
可用的API选项
/// 定义默认的 [selectedTab]
final T activeTab;
/// 定义这个小部件的 [tabs]
/// 每个 [tab] 必须定义一个 [TabRoutesDefinition]
final Map<T, TabRoutesDefinition> tabs;
/// 定义 [bodyBuilder],如果你需要一些非常自定义的东西,比如将标签放在不同的位置(例如顶部),你可以放置 [tabs] 和 [tabView] 在一个自定义布局排列
final BodyBuilder bodyBuilder;
/// 构建每个标签的自定义 [tab] 小部件,请确保调用 [cb] 参数,如果你使用的是可以处理触摸事件的自定义 [GestureDetector | InkWell] 或其他小部件
/// 调用 [cb] 将触发状态构建并按预期更改标签内容
final TabBuilder<T> tabBuilder;
/// 定义 [Color] 用于 [tab] 激活时的 [title] 和 [icon]
final Color activeTabColor;
/// 定义 [Color] 用于 [tab] 未激活时的 [title] 和 [icon]
final Color inactiveTabColor;
/// 定义 [tab] 的点击处理器
final Function(T) tabTap;
/// 构建自定义 [title] 小部件
final TitleBuilder<T> titleBuilder;
/// 构建自定义 [icon] 小部件
final IconBuilder<T> iconBuilder;
/// 每次生成路由时都会被调用,它传递了实际的 [RouteSettings],
/// 拥有该导航器的标签 [T],
/// 用于生成页面的实际路线 [EnumClass],
/// 基于定义的路线的页面构建器 [WidgetBuilder]。
/// 这可以用来返回一个自定义的页面路由包装器,如 `MaterialPageRoute` 或者用自定义动画包装构建器等
final OnGenerateRouteFn<T> onGenerateRoute;
/// 设置 [activetab],如果没有定义,则默认为 [tabs] 中第一个 [tab] 键
final T activeTab;
/// 更改默认标签容器背景
final Color tabContainerBackgroundColor;
/// [didPop] 导航观察器回调
final void Function(T tab, Route route, Route previousRoute) didPop;
/// [didPush] 导航观察器回调
final void Function(T tab, Route route, Route previousRoute) didPush;
/// [didRemove] 导航观察器回调
final void Function(T tab, Route route, Route previousRoute) didRemove;
/// [didReplace] 导航观察器回调
final void Function(T tab, Route newRoute, Route oldRoute) didReplace;
/// 如果 [true],则会实现 [WillPopScope] 小部件用于嵌套导航视图,如果 [false],
/// 后退导航将针对根导航器
/// 默认为 [true]
final bool overridePopBehavior;
/// 设置自定义 [height] 用于标签容器
/// 默认为 [60]
/// 如果定义了 [bodyBuilder],则此属性不会生效
final double tabsHeight;
/// 定义一个自定义构建器来包装每个标签内容的小部件,
/// 这对于构建一个实现自定义动画的小部件很有用
/// 参数:
/// [BuildContext] 当前上下文
/// [EnumClass] 当前正在构建的 `tab`
/// [bool] 当前 `tab` 是否激活
/// [Widget] 实际要包裹的内容,你需要将此小部件作为你小部件实现的子级
final TabContentWrapBuilder contentWrapBuilder;
/// 定义自定义持续时间用于实现的不透明度过渡
/// 如果你实现了自定义 [contentWrapBuilder],则此选项无效果
/// 默认为 [Duration(400ms)]
final Duration contentAnimationDuration;
截图
获取示例代码
你可以查看 示例代码。
示例代码
import 'package:built_collection/built_collection.dart';
import 'package:built_tab_navigator/built_tab_navigator.dart';
import 'package:built_value/built_value.dart';
import 'package:flutter/material.dart';
import 'example1_routes.dart';
import 'example2_routes.dart';
import 'example3_routes.dart';
part 'main.g.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
[@override](/user/override)
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: BuiltTabNavigator(
activeTabColor: Colors.red,
inactiveTabColor: Colors.white,
bodyBuilder: (context, tabs, tabView) {
return Column(
children: <Widget>[
Material(
elevation: 9,
color: Colors.blue[200],
child: Container(
height: 100,
child: Row(
children: tabs,
),
),
),
Expanded(
child: tabView,
),
],
);
},
tabs: {
ExampleTabs.example1: TabRoutesDefinition(
initialRoute: Example1Routes.root,
routes: example1Routes,
tabTitle: "Example 1",
tabIcon: Icons.ac_unit,
),
ExampleTabs.example2: TabRoutesDefinition(
initialRoute: Example2Routes.root,
routes: example2Routes,
tabTitle: "Example 2",
tabIcon: Icons.accessibility_new,
),
ExampleTabs.example3: TabRoutesDefinition(
initialRoute: Example2Routes.root,
routes: example3Routes,
tabTitle: "Example 3",
tabIcon: Icons.adb,
),
},
),
);
}
}
class ExampleTabs extends EnumClass {
static const ExampleTabs example1 = _$example1;
static const ExampleTabs example2 = _$example2;
static const ExampleTabs example3 = _$example3;
const ExampleTabs._(String name) : super(name);
static BuiltSet<ExampleTabs> get values => _$values;
static ExampleTabs valueOf(String name) => _$valueOf(name);
}
更多关于Flutter标签页导航插件built_tab_navigator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter标签页导航插件built_tab_navigator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用 built_tab_navigator
插件在 Flutter 中实现标签页导航的代码案例。built_tab_navigator
并不是一个官方或广泛认知的 Flutter 插件,但假设它是一个提供标签页导航功能的自定义插件,我们可以模拟一个类似的实现来展示其可能的使用方法。
通常,在 Flutter 中实现标签页导航可以使用 TabBar
和 TabBarView
,但为了符合你的要求,我将展示一个假设的 built_tab_navigator
的使用方式。
假设的 built_tab_navigator
使用示例
首先,假设 built_tab_navigator
提供了如下功能:
- 一个
BuiltTabNavigator
小部件,接受一组标签页和一个初始页面。 - 每个标签页通过一个配置对象来定义。
以下是一个假设的 built_tab_navigator
使用示例:
import 'package:flutter/material.dart';
import 'package:built_tab_navigator/built_tab_navigator.dart'; // 假设的包路径
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Tab Navigator Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: BuiltTabNavigatorDemo(),
);
}
}
class BuiltTabNavigatorDemo extends StatefulWidget {
@override
_BuiltTabNavigatorDemoState createState() => _BuiltTabNavigatorDemoState();
}
class _BuiltTabNavigatorDemoState extends State<BuiltTabNavigatorDemo> {
final List<TabItem> tabItems = [
TabItem(title: 'Home', icon: Icons.home, page: HomePage()),
TabItem(title: 'Search', icon: Icons.search, page: SearchPage()),
TabItem(title: 'Profile', icon: Icons.person, page: ProfilePage()),
];
@override
Widget build(BuildContext context) {
// 假设 BuiltTabNavigator 是提供的标签页导航小部件
return BuiltTabNavigator(
items: tabItems,
initialIndex: 0, // 初始选中的标签页索引
onTabSelected: (index) {
// 可选的:标签页选中时的回调
print('Selected tab: $index');
},
);
}
}
// 假设的 TabItem 配置类
class TabItem {
final String title;
final IconData icon;
final Widget page;
TabItem({required this.title, required this.icon, required this.page});
}
// 假设的 BuiltTabNavigator 小部件实现(模拟)
class BuiltTabNavigator extends StatefulWidget {
final List<TabItem> items;
final int initialIndex;
final ValueChanged<int>? onTabSelected;
BuiltTabNavigator({
required this.items,
required this.initialIndex,
this.onTabSelected,
});
@override
_BuiltTabNavigatorState createState() => _BuiltTabNavigatorState();
}
class _BuiltTabNavigatorState extends State<BuiltTabNavigator> {
int _selectedIndex = 0;
@override
void initState() {
super.initState();
_selectedIndex = widget.initialIndex;
}
void _onTabTapped(int index) {
setState(() {
_selectedIndex = index;
widget.onTabSelected?.call(index);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Tab Navigator Demo'),
bottom: TabBar(
tabs: widget.items.map((item) {
return Tab(
icon: Icon(item.icon),
text: item.title,
);
}).toList(),
currentIndex: _selectedIndex,
onTabSelected: _onTabTapped,
),
),
body: TabBarView(
children: widget.items.map((item) => item.page).toList(),
controller: TabController(length: widget.items.length, vsync: Vsyncer(), initialIndex: _selectedIndex),
),
);
}
}
// 简单的 Vsync 实现,用于 TabController
class Vsyncer implements TickerProvider {
@override
Ticker createTicker(TickerCallback onTick) {
throw UnimplementedError();
}
@override
bool disposeTicker(Ticker ticker) {
throw UnimplementedError();
}
}
// 示例页面
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: Text('Home Page'));
}
}
class SearchPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: Text('Search Page'));
}
}
class ProfilePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: Text('Profile Page'));
}
}
注意事项
- 包导入:
import 'package:built_tab_navigator/built_tab_navigator.dart';
是一行假设的代码,实际使用时需要替换为真实的包路径。 - TickerProvider:
Vsyncer
类是一个简化的TickerProvider
实现,用于TabController
。在实际应用中,你可能会使用SingleTickerProviderStateMixin
或其他合适的TickerProvider
。 - 自定义实现:上述代码展示了如何使用
TabBar
和TabBarView
来模拟一个标签页导航器的功能。如果built_tab_navigator
真实存在,其使用方式可能会有所不同,但基本思想类似。
希望这个示例能帮你理解如何在 Flutter 中实现标签页导航。如果有实际的 built_tab_navigator
插件,请参考其官方文档以获取准确的使用方法。