我正在底部导航栏的浮动操作按钮中添加动画图标。但是在添加2个按钮之后,我的FAB向下移动了。
我正在使用以下代码
Widget _buildCenterTab(){
return new Column(
mainAxisSize: MainAxisSize.min,
children: new List.generate(icons.length, (int index) {
Widget child = new Container(
height: 56.0,
width: 56.0,
alignment: FractionalOffset.topCenter,
child: new ScaleTransition(
scale: new CurvedAnimation(
parent: _controller,
curve: new Interval(
0.0,
1.0 - index / icons.length / 2.0,
curve: Curves.easeOut
),
),
child: new FloatingActionButton(
heroTag: null,
backgroundColor: blueColor,
mini: true,
child: new Icon(icons[index], color: Colors.white),
onPressed: () {},
),
),
);
return child;
}).toList()..add(
new FloatingActionButton(
heroTag: null,
child: new AnimatedBuilder(
animation: _controller,
builder: (BuildContext context, Widget child) {
return new Transform(
transform: new Matrix4.rotationZ(_controller.value * 0.5 * math.pi),
alignment: FractionalOffset.center,
child: new Icon(
_controller.isDismissed
? Icons.add
: Icons.close),
);
},
),
onPressed: () {
if (_controller.isDismissed) {
_controller.forward();
} else {
_controller.reverse();
}
},
),
),
);
}
答案 0 :(得分:0)
解决这个问题的一种方法是创建自己的FloatingActionButtonLocation
class _CustomCenterDockedFloatingActionButtonLocation extends FloatingActionButtonLocation {
const _CustomCenterDockedFloatingActionButtonLocation();
@override
Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry) {
final double fabX = (scaffoldGeometry.scaffoldSize.width - scaffoldGeometry.floatingActionButtonSize.width) / 2.0;
return Offset(fabX, getDockedY(scaffoldGeometry));
}
double getDockedY(ScaffoldPrelayoutGeometry scaffoldGeometry) {
final double contentBottom = scaffoldGeometry.contentBottom;
final double bottomSheetHeight = scaffoldGeometry.bottomSheetSize.height;
final double fabHeight = scaffoldGeometry.floatingActionButtonSize.height;
final double snackBarHeight = scaffoldGeometry.snackBarSize.height;
double fabY = contentBottom - fabHeight / 2.0;
// The FAB should sit with a margin between it and the snack bar.
if (snackBarHeight > 0.0)
fabY = math.min(fabY, contentBottom - snackBarHeight - fabHeight - kFloatingActionButtonMargin);
// The FAB should sit with its center in front of the top of the bottom sheet.
if (bottomSheetHeight > 0.0)
fabY = math.min(fabY, contentBottom - bottomSheetHeight - fabHeight / 2.0);
final double maxFabY = scaffoldGeometry.scaffoldSize.height - fabHeight;
return math.min(maxFabY, fabY);
}
}
这使用的是与the source中提取的FloatingActionButtonLocation.centerDocked
相同的代码,然后可以像这样在脚手架中使用它:
Scaffold(
body: Container(),
floatingActionButton: _buildCenterTab(),
floatingActionButtonLocation: _CustomCenterDockedFloatingActionButtonLocation(),
...
);
答案 1 :(得分:0)
检查此代码,您可以用容器包装整列,并使用transform属性将其向上移56/2使其居中。
import 'dart:math' as math;
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
home: HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget{
@override
HomeScreenState createState() {
return new HomeScreenState();
}
}
class HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin{
List<IconData> icons = [(Icons.add),(Icons.clear),(Icons.forward)];
AnimationController _controller ;
@override
void initState() {
_controller = AnimationController(vsync: this,duration: Duration(seconds: 1));
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(Icons.map),
title: Text("Hi")),
BottomNavigationBarItem(
icon:Icon(Icons.image),
title:Text("There"),
)
]
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: Container(
width: 56.0,
height: 56.0*4,
transform: Matrix4.translationValues(0, -56/2, 0),
child: new Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
children: new List.generate(icons.length, (int index) {
Widget child = new Container(
height: 56.0,
width: 56.0,
alignment: FractionalOffset.topCenter,
child: new ScaleTransition(
scale: new CurvedAnimation(
parent: _controller,
curve: new Interval(
0.0,
1.0 - index / icons.length / 2.0,
curve: Curves.easeOut
),
),
child: new FloatingActionButton(
heroTag: null,
backgroundColor: Colors.blue,
mini: true,
child: new Icon(icons[index], color: Colors.white),
onPressed: () {},
),
),
);
return child;
}).toList()..add(
new FloatingActionButton(
heroTag: null,
child: new AnimatedBuilder(
animation: _controller,
builder: (BuildContext context, Widget child) {
return new Transform(
transform: new Matrix4.rotationZ(_controller.value * 0.5 * math.pi),
alignment: FractionalOffset.center,
child: new Icon(
_controller.isDismissed
? Icons.add
: Icons.close),
);
},
),
onPressed: () {
if (_controller.isDismissed) {
_controller.forward();
} else {
_controller.reverse();
}
},
),
),
),
),
);
}
}