📅  最后修改于: 2023-12-03 15:15:08.274000             🧑  作者: Mango
Flutter 凸底条是一个常见的 UI 组件,可以给应用增添美观度和用户交互性。凸底条通常用于底部菜单导航栏,提供应用的核心功能和浏览多个页面的方式。Flutter 提供了内置的凸底条组件,可以轻松实现此功能。下面详细介绍凸底条的使用方法。
在 Flutter 中,可以使用 BottomNavigationBar 组件来实现凸底条。BottomNavigationBar 中有 items 属性,它的值应该为一个包含 BottomNavigationBarItem 的数组。BottomNavigationBarItem 包含了需要显示在凸底条上的每个条目。每个条目都包含一个图标和标题文字。下面是一个实现简单的凸底条的例子:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
static const String _title = 'Flutter Bottom Navigation Bar Example';
@override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: BottomNavigation(),
);
}
}
class BottomNavigation extends StatefulWidget {
BottomNavigation({Key? key}) : super(key: key);
@override
_BottomNavigationState createState() => _BottomNavigationState();
}
class _BottomNavigationState extends State<BottomNavigation> {
int _currentIndex = 0;
final List<Widget> _children = [
PlaceholderWidget(Colors.white),
PlaceholderWidget(Colors.deepOrange),
PlaceholderWidget(Colors.green)
];
void onTabTapped(int index) {
setState(() {
_currentIndex = index;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Bottom Navigation Bar Example'),
),
body: _children[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
onTap: onTabTapped,
currentIndex: _currentIndex,
items: [
BottomNavigationBarItem(
icon: new Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: new Icon(Icons.mail),
label: 'Messages',
),
BottomNavigationBarItem(
icon: Icon(Icons.person), label: 'Profile')
],
),
);
}
}
class PlaceholderWidget extends StatelessWidget {
final Color color;
PlaceholderWidget(this.color);
@override
Widget build(BuildContext context) {
return Container(
color: color,
);
}
}
在这个例子中,我们定义了一个 BottomNavigation 组件作为主组件,并定义了几个常规的页面片段作为凸底条条目的子页面。最后我们将它们放在 BottomNavigationBarItem 组件中,并用 BottomNavigationBar 进行渲染形成凸底条。下面是效果图。
Flutter 的 BottomNavigationBar 组件默认提供了简单的动画。但是,我们可以使用 Flutter 的动画库来自定义凸底条的动画过渡效果,从而增加应用的交互性。例如,在 tab 之间切换时缩放图标,可以给用户更加明显的反馈。下面是一个自定义的凸底条动画的示例:
class CustomBottomNavigationBar extends StatefulWidget {
final List<BottomBarItem> items;
final ValueChanged<int> onTap;
final int currentIndex;
CustomBottomNavigationBar({
required this.items,
required this.onTap,
required this.currentIndex,
}) : assert(items.length > 1, 'Items cannot be less than 2');
@override
_CustomBottomNavigationBarState createState() =>
_CustomBottomNavigationBarState();
}
class _CustomBottomNavigationBarState
extends State<CustomBottomNavigationBar>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: Duration(milliseconds: 300),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return BottomNavigationBar(
currentIndex: widget.currentIndex,
onTap: (index) {
if (widget.currentIndex != index) {
setState(() {
_controller.reset();
_controller.forward();
});
widget.onTap(index);
}
},
items: List.generate(
widget.items.length,
(index) => buildBottomNavigationBarItem(
index: index,
item: widget.items[index],
animation: _controller,
),
),
type: BottomNavigationBarType.fixed,
);
}
BottomNavigationBarItem buildBottomNavigationBarItem({
required int index,
required BottomBarItem item,
required AnimationController animation,
}) {
ColorTween colorTween;
if (widget.currentIndex == index) {
colorTween = ColorTween(
begin: item.inactiveColor,
end: item.activeColor,
);
} else {
colorTween = ColorTween(
begin: item.activeColor,
end: item.inactiveColor,
);
}
return BottomNavigationBarItem(
icon: ScaleTransition(
scale: Tween<double>(begin: 1.0, end: 1.2).animate(
CurvedAnimation(
parent: animation,
curve: Interval(
0.0,
0.5,
curve: index == 0
? Curves.easeOutSine
: Curves.easeInSine,
),
),
),
child: Icon(
item.icon,
color: colorTween.evaluate(animation),
),
),
label: item.label,
);
}
}
class BottomBarItem {
final IconData icon;
final String label;
final Color activeColor;
final Color inactiveColor;
BottomBarItem({
required this.icon,
required this.label,
required this.activeColor,
required this.inactiveColor,
});
}
在此例中,我们定义了 CustomBottomNavigationBar 组件并注入一组 BottomBarItem 实例。同时,还传递了 onTap 回调函数、currentIndex 和对应的 BottomNavigationBarItem 以及动画控制器。buildBottomNavigationBarItem 函数只是一个简单的封装,用于构建图标动画,当用户从一个标签切换到另一个标签时,每个图标按规定的曲线轻轻地缩小和放大。
最后,使用此自定义函数来渲染我们的凸底条:
class _CustomBarAnimationState extends State<CustomBarAnimation>
with TickerProviderStateMixin {
static const barHeight = 72.0;
late Animation<Offset> _animation;
late AnimationController _controller;
int _currentIndex = 0;
final List<Widget> _children = [
PlaceholderWidget(Colors.white),
PlaceholderWidget(Colors.deepOrange),
PlaceholderWidget(Colors.green),
];
final List<BottomBarItem> _items = [
BottomBarItem(
icon: Icons.home,
label: 'Home',
activeColor: Colors.blue,
inactiveColor: Colors.grey,
),
BottomBarItem(
icon: Icons.mail,
label: 'Messages',
activeColor: Colors.blue,
inactiveColor: Colors.grey,
),
BottomBarItem(
icon: Icons.person,
label: 'Profile',
activeColor: Colors.blue,
inactiveColor: Colors.grey,
),
];
void _onTap(int index) {
setState(() {
_currentIndex = index;
});
}
@override
void initState() {
_controller = AnimationController(
vsync: this,
duration: Duration(milliseconds: 800),
);
_animation = Tween<Offset>(
begin: Offset.zero,
end: Offset(0, 1),
).animate(
CurvedAnimation(
parent: _controller,
curve: Curves.easeInOutExpo,
),
);
super.initState();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Custom Bottom Navigation Bar Animation'),
),
body: Stack(
alignment: Alignment.bottomCenter,
children: [
SizedBox(
height: MediaQuery.of(context).size.height - barHeight,
child: _children[_currentIndex],
),
SlideTransition(
position: _animation,
child: Container(
height: barHeight,
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 5,
),
],
),
child: CustomBottomNavigationBar(
items: _items,
currentIndex: _currentIndex,
onTap: _onTap,
),
),
),
],
),
);
}
}
如图所示,自定义组件提供了一种更细微的交互效果:
Flutter 对凸底条的支持,使得应用程序增量增加了和用户交互式的用户标准,也提供了自定义动画的空间,从而为应用程序提供了更多的个性化。如果您想使用凸底条组件来改进您的应用程序,请查看官方文档,了解更多信息。