因此,我试图使用Flutter及其预定义的小部件构建“自定义底部导航”栏,我希望将栏项目(按钮)展开以填充空白区域,但在动画过程中始终会出现“溢出”错误。我将在下面分享我的代码,希望有人可以提供一些帮助:)
也尝试了Flexible但同样的问题。
StringUtils
,您可以在脚手架内部以这种方式使用它:
import 'package:flutter/material.dart';
class AnimatedBottomBar extends StatefulWidget {
final List<BarItem> barItems;
final Duration animationDuration;
final Function onBarTap;
final BarStyle barStyle;
final Color unselectedBackgroundColor;
final Color unselectedIconColor;
final EdgeInsetsGeometry padding;
AnimatedBottomBar(
{this.barItems,
this.animationDuration = const Duration(milliseconds: 500),
this.onBarTap,
this.barStyle,
this.unselectedBackgroundColor,
this.unselectedIconColor,
this.padding});
@override
_AnimatedBottomBarState createState() => _AnimatedBottomBarState();
}
class _AnimatedBottomBarState extends State<AnimatedBottomBar>
with TickerProviderStateMixin {
int selectedBarIndex = 1;
@override
Widget build(BuildContext context) {
return Material(
elevation: 30.0,
child: Padding(
padding: widget.padding == null
? EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0)
: widget.padding,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: _buildBarItems(),
),
),
);
}
List<Widget> _buildBarItems() {
List<Widget> _barItems = List();
for (int i = 0; i < widget.barItems.length; i++) {
BarItem item = widget.barItems[i];
bool isSelected = selectedBarIndex == i;
_barItems.add(Flexible(
fit: FlexFit.loose,
flex: isSelected ? 7 : 4,
child: AnimatedSize(
duration: widget.animationDuration,
vsync: this,
child: InkWell(
splashColor: Colors.transparent,
onTap: () {
setState(() {
selectedBarIndex = i;
widget.onBarTap(selectedBarIndex);
});
},
child: AnimatedContainer(
padding:
const EdgeInsets.symmetric(horizontal: 8.0, vertical: 8.0),
duration: widget.animationDuration,
decoration: BoxDecoration(
color: isSelected
? item.color.withOpacity(0.15)
: widget.unselectedBackgroundColor != null
? widget.unselectedBackgroundColor
: Colors.transparent,
borderRadius: BorderRadius.all(Radius.circular(20))),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Stack(
children: <Widget>[
Icon(
item.iconData,
color: isSelected
? item.color
: widget.unselectedIconColor,
size: widget.barStyle.iconSize,
),
if (item.notificationCount > 0)
Positioned(
right: 0.0,
top: 0.0,
child: AnimatedContainer(
duration: Duration(seconds: 1),
height: widget.barStyle.iconSize / 2,
width: widget.barStyle.iconSize / 2,
child: Center(
child: Text(
widget.barItems[i].notificationCount < 99
? '${widget.barItems[i].notificationCount}'
: '99',
textAlign: TextAlign.center,
maxLines: 1,
style: TextStyle(
fontSize: item.notificationCount > 9
? widget.barStyle.fontSize / 2
: widget.barStyle.fontSize / 2 + 2,
color: Colors.white,
fontWeight: FontWeight.w600,
height: 0.85),
),
),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.red.shade600,
borderRadius:
BorderRadius.all(Radius.circular(4.0))),
),
),
],
),
if (isSelected)
SizedBox(
width: 10.0,
),
AnimatedSize(
duration: widget.animationDuration,
curve: Curves.easeInOut,
vsync: this,
child: Text(
isSelected ? item.text : "",
style: TextStyle(
color: item.color,
fontWeight: widget.barStyle.fontWeight,
fontSize: widget.barStyle.fontSize),
),
)
],
),
),
),
),
));
_barItems.add(SizedBox(width: 4.0,));
}
return _barItems;
}
}
class BarStyle {
final double fontSize, iconSize;
final FontWeight fontWeight;
BarStyle(
{this.fontSize = 18.0,
this.iconSize = 32,
this.fontWeight = FontWeight.w600});
}
class BarItem {
final String text;
final IconData iconData;
final Color color;
int notificationCount;
setNotificationCount(int i) {
this.notificationCount = i;
}
BarItem({this.text, this.iconData, this.color, this.notificationCount = 0});
}
注意:不要忘了像这样预定义项目列表,并且当列表包含5个项目时,它会显示所需的结果,因为5个项目填满了所有空间(但请先删除扩展的小部件)。>
Scaffold(
bottomNavigationBar:AnimatedBottomBar(
barItems: barItems,
animationDuration: const Duration(milliseconds: 200),
barStyle: BarStyle(
fontSize: 25.0, iconSize: 30.0, fontWeight: FontWeight.w500),
unselectedBackgroundColor: Colors.grey.shade600,
unselectedIconColor: Colors.yellow,
onBarTap: (index) {
setState(() {
_index = index;
barItems[index].notificationCount++;
});
}); );
我希望有人可以帮我解决这个问题,因为它使我感到困惑:)
我还计划将其作为颤振包,供人们在按预期方式使用后使用。它还包含一个通知选项,如下面的此GIF所示: