floatingActionButton的一些常见用法我就不说了,如果遇到跟bottomNavigationBar结合使用的时候,可以参考一下这篇文章。
需求上要在bottomNavigationBar中间加上一个自定义的按钮,这个按钮和BottomNavigationBarItem要在同一水平线上居中,floatingActionButtonLocation已经提供了很多个位置,但是不能满足我们的需求,所以自定了这个类FloatingActionButtonLocation:
class FloatingButtonCustomLocation extends FloatingActionButtonLocation {
FloatingActionButtonLocation location;
final double offsetX; // X方向的偏移量
final double offsetY; // Y方向的偏移量
FloatingButtonCustomLocation(this.location,
{this.offsetX = 0, this.offsetY = 0});
@override
Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry) {
Offset offset = location.getOffset(scaffoldGeometry);
return Offset(offset.dx + offsetX, offset.dy + offsetY);
}
}
这样子就可以修改按钮的位置:
floatingActionButton: SizedBox(
child: FloatingActionButton(
backgroundColor: Colors.transparent,
child: Image.asset("images/tab/plus.png",
width: 40, height: 40, fit: BoxFit.cover),
onPressed: () {},
),
),
floatingActionButtonLocation: FloatingButtonCustomLocation(
FloatingActionButtonLocation.centerDocked,
offsetY: Platform.isIOS && Screen.bottomBarHeight > 0 ? 25 : -10,
offsetX: 0),
看到效果ok了,但是会有一个问题,切换tab的时候中间的按钮会闪动,现象如下:
后来查看文档发现
Scaffold还有一个属性floatingActionButtonAnimator
/// If null, the [ScaffoldState] will use the default animator, [FloatingActionButtonAnimator.scaling].
final FloatingActionButtonAnimator? floatingActionButtonAnimator;
原来是ScaffoldState搞的怪,Scaffold如果不实现这个动画,默认就会实现缩放的一个效果,setState的时候就会触发这个动画:
onTap: (int index) {
setState(() {
_currentIndex = index; // 这里会触发floatingActionButton动画
});
},
如果没有自定义floatingActionButtonLocation是不会有这个问题的,猜测是自定义floatingActionButtonLocation导致位置变化,导致每次都会刷新触发动画。
来到正题,我们需要自定义FloatingActionButtonAnimator
class ScalingCustomAnimation extends FloatingActionButtonAnimator{
late double _x;
late double _y;
@override
Offset getOffset({required Offset begin, required Offset end, required double progress}) {
_x = begin.dx +(end.dx - begin.dx)*progress ;
_y = begin.dy +(end.dy - begin.dy)*progress;
return Offset(_x,_y);
}
@override
Animation<double> getRotationAnimation({required Animation<double> parent}) {
return Tween<double>(begin: 1.0, end: 1.0).animate(parent);
}
@override
Animation<double> getScaleAnimation({required Animation<double> parent}) {
return Tween<double>(begin: 1.0, end: 1.0).animate(parent);
}
}
使用:
floatingActionButton: SizedBox(
child: FloatingActionButton(
backgroundColor: Colors.transparent,
child: Image.asset("images/tab/plus.png",
width: 40, height: 40, fit: BoxFit.cover),
onPressed: () {},
),
),
// floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButtonLocation: FloatingButtonCustomLocation(
FloatingActionButtonLocation.centerDocked,
offsetY: Platform.isIOS && Screen.bottomBarHeight > 0 ? 25 : -10,
offsetX: 0),
floatingActionButtonAnimator: ScalingCustomAnimation()
stop后重新运行,发现不会闪动了,大功告成!