[英]Animated FloatingActionButton in Stack don't trigger onPressed event
I've created an animated Floating Action Button (FAB) menu: Main FAB which spawns other FABs when clicked. 我创建了一个动画浮动操作按钮(FAB)菜单:主FAB在单击时生成其他FAB。 It is based on several online tutorials. 它基于几个在线教程。
Works fine besides one major issue: The spawned FABs don't trigger an onPressed event. 除了一个主要问题之外还可以正常工作:生成的FAB不会触发onPressed事件。
Seems like there's a problem with the combination of transform animation and the stack widget (which the FABs are children of). 似乎变换动画和堆栈小部件(FAB是其子代)的组合存在问题。 Works fine if I replace the stack with a row... 如果我用一行替换堆栈,工作正常......
Seems like the issue was addressed here, but without a proper solution: FloatingActionButton onPressed not triggering 似乎这里解决了这个问题,但没有一个合适的解决方案: FloatingActionButton onPressed没有触发
Here's the complete code for that FAB menu. 这是FAB菜单的完整代码。 Just supply it a list with buttons data, similar to this one: 只需提供一个包含按钮数据的列表,类似于这个:
List<Map<String, dynamic>> _buttonsData = [
{'color': Colors.green ,'icon': Icons.stop},
{'color': Colors.blue ,'icon': Icons.subway},
{'color': Colors.green ,'icon': Icons.add},];
FancyFab2(_buttonsData, null)
The code: 编码:
import 'package:flutter/material.dart';
class FancyFab extends StatefulWidget {
FancyFab(this._buttonsData, this._onSelected);
final List<Map<String, dynamic>> _buttonsData;
final ValueChanged<int> _onSelected;
@override
createState() => FancyFabState(_buttonsData, _onSelected);
}
class FancyFabState extends State<FancyFab> with SingleTickerProviderStateMixin {
final List<Map<String, dynamic>> _buttonsData;
final ValueChanged<int> _onSelected;
// state vars
AnimationController _controller;
Animation <double> _transform;
bool _isOpened = false;
FancyFabState(this._buttonsData, this._onSelected);
@override
void initState() {
// call base
super.initState();
// _controller
_controller = AnimationController(
duration: Duration(milliseconds: 100),
vsync: this
);
_transform = Tween<double>(
begin: 0.0,
end: -64.0,
).animate(
CurvedAnimation(
parent: _controller,
curve: Curves.fastOutSlowIn
),
);
}
@override
void dispose() {
// controller
_controller.dispose();
// call base
super.dispose();
}
@override
Widget build(BuildContext context) {
return _buildFab(_controller);
}
Widget _buildFab(AnimationController controller) {
return AnimatedBuilder(
animation: controller,
builder: (context, builder) {
return Stack(
children: List.generate(_buttonsData.length, (index) => _buildStackWidget(context, index))
);
}
);
}
Widget _buildStackWidget(BuildContext context, int index) {
Map<String, dynamic> buttonData = _buttonsData[index];
if (index == _buttonsData.length - 1)
return _buildMenuButton(index, buttonData);
else
return _buildMenuItem(index, buttonData);
}
Widget _buildMenuItem(int index, Map<String, dynamic> buttonData) {
return Transform.translate(
offset: Offset((1 + index) * _transform.value, 0.0),
child: FloatingActionButton(
heroTag: 100 + index,
backgroundColor: buttonData['color'],
//onPressed: () => _onSelected(index),
onPressed: () => print('click'),
child: Icon(buttonData['icon']),
),
);
}
Widget _buildMenuButton(int index, Map<String, dynamic> buttonData) {
return FloatingActionButton(
heroTag: 200,
backgroundColor: buttonData['color'],
onPressed: _toggle,
child: Icon(buttonData['icon']),
);
}
void _toggle() {
print('toggle');
_isOpened = !_isOpened;
if (true == _isOpened)
_controller.forward();
else
_controller.reverse();
}
}
That's because you are moving the items
outside your Stack
so you can't hitTest
on those positions. 那是因为你正在移动Stack
外的items
所以你不能在这些位置上hitTest
。
I modified a few lines of your code to make it works : 我修改了几行代码以使其工作:
Add constraints to your Stack
(you can use SizedBox also) , I'm using container to set a different color of background. 向Stack
添加约束(您也可以使用SizedBox),我使用容器来设置不同颜色的背景。
Widget _buildFab(AnimationController controller) { return AnimatedBuilder( animation: controller, builder: (context, builder) { return Container( width: MediaQuery.of(context).size.width, height: 100, color: Colors.blueGrey, child: Stack( children: List.generate(_buttonsData.length, (index) => _buildStackWidget(context, index))), ); }); }
Center your items
居中items
Widget _buildMenuItem(int index, Map<String, dynamic> buttonData) { return Center( child: Transform.translate( offset: Offset((1 + index) * _transform.value, 0.0), child: FloatingActionButton( heroTag: 100 + index, backgroundColor: buttonData['color'], //onPressed: () => _onSelected(index), onPressed: () => print('click'), child: Icon(buttonData['icon']), ), ), ); } Widget _buildMenuButton(int index, Map<String, dynamic> buttonData) { return Center( child: FloatingActionButton( heroTag: 200, backgroundColor: buttonData['color'], onPressed: _toggle, child: Icon(buttonData['icon']), ), ); }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.