Trying to implement a floating action button that extends in two dimension and then show some more option of floating action button. Somehow able to animated the child widget of the floating action button to their correct position, using the Transform Widget, but when I try to press on the child widget, i.e. the widgets that come out on pressing the floating action button, they do not respond to the onPressed handler. Tried many different thing like IgnorePointer, stacked rows and Columns, AnimatedBuilder,etc. but was unable to find the correct solution. It was like sometimes used to get the UI correct then the gesture was not detected and if the gesture were detected the UI got distorted. And I am somewhat new to flutter. Any help in sorting out this issue would be appreciated.
Here is my Code:
main.dart
import "package:flutter/material.dart";
import 'myhome.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primaryColor: Colors.blue,
),
title: "Custom Expandable FAB",
home: MyHome(),
);
}
}
myhome.dart
import 'package:flutter/material.dart';
import 'package:tester_project/customFAB.dart';
class MyHome extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
extendBody: true,
backgroundColor: Colors.white,
floatingActionButton: CustomFab(),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
bottomNavigationBar: BottomAppBar(
color: Colors.blue,
shape: CircularNotchedRectangle(),
child: Container(
height: 55,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
icon: Icon(Icons.search),
onPressed: () {},
),
IconButton(
icon: Icon(Icons.menu),
onPressed: () {},
),
],
),
),
),
appBar: AppBar(
title: Text("Custom FAB"),
),
body: Container(
alignment: Alignment.center,
child: Text("Click on Fab to expand"),
color: Colors.white,
),
);
}
}
CustomFab.dart
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
class CustomFab extends StatefulWidget {
@override
_CustomFabState createState() => _CustomFabState();
}
class _CustomFabState extends State<CustomFab>
with SingleTickerProviderStateMixin {
AnimationController _animationController;
Animation<double> _translateAnimation;
Animation<double> _rotationAnimation;
Animation<double> _iconRotation;
bool _isExpanded = false;
void animate() {
if (!_isExpanded) {
_animationController.forward();
} else {
_animationController.reverse();
}
_isExpanded = !_isExpanded;
}
Widget fab1() {
return Container(
height: 60,
width: 60,
child: FittedBox(
child: FloatingActionButton(
heroTag: "btn3",
backgroundColor: Color(0xffFFC852),
elevation: 0,
onPressed: () {
print("pressed");
},
),
),
);
}
Widget fab2() {
return Container(
height: 60,
width: 60,
child: FittedBox(
child: FloatingActionButton(
heroTag: "btn4",
child: Transform.rotate(
angle: _iconRotation.value,
child: Icon(Icons.home),
),
elevation: _isExpanded ? 5 : 0,
backgroundColor: Color(0xffE5E4F4),
onPressed: () {
print("Pressed");
},
),
),
);
}
Widget fab3() {
return Container(
height: 60,
width: 60,
child: FittedBox(
child: FloatingActionButton(
heroTag: "btn5",
child: Transform.rotate(
angle: _rotationAnimation.value,
child: Icon(Icons.add),
),
backgroundColor: Color(0xffFFC852),
onPressed: () async {
await Permission.contacts.request();
if (await Permission.contacts.status.isGranted) {
animate();
}
},
),
),
);
}
@override
void initState() {
_animationController =
AnimationController(vsync: this, duration: Duration(milliseconds: 400))
..addListener(() {
setState(() {});
});
_translateAnimation = Tween<double>(begin: 0, end: 80)
.chain(
CurveTween(
curve: _isExpanded ? Curves.fastOutSlowIn : Curves.bounceOut,
),
)
.animate(_animationController);
_iconRotation = Tween<double>(begin: 3.14 / 2, end: 0)
.chain(
CurveTween(curve: Curves.bounceInOut),
)
.animate(_animationController);
_rotationAnimation = Tween<double>(begin: 0, end: 3 * 3.14 / 4)
.chain(
CurveTween(
curve: Curves.bounceInOut,
),
)
.animate(_animationController);
super.initState();
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Stack(
clipBehavior: Clip.none,
children: [
Transform(
transform:
Matrix4.translationValues(0, -_translateAnimation.value, 0),
child: fab1(),
),
Transform(
transform:
Matrix4.translationValues(-_translateAnimation.value, 0, 0),
child: fab2(),
),
fab3(),
],
);
}
}
Floating action button before and after expansion
