To create a draggable and expandable floating action menu in Flutter, we can use a combination of the Stack, AnimatedContainer, and GestureDetector widgets.
Here’s an example code snippet that demonstrates how to make a draggable and expandable floating action menu in Flutter:
import 'package:flutter/material.dart';
void main() {
runApp( MyFABMenuScreen());
}
class MyFABMenuScreen extends StatefulWidget {
@override
_MyFABMenuScreenState createState() => _MyFABMenuScreenState();
}
class _MyFABMenuScreenState extends State<MyFABMenuScreen>
with SingleTickerProviderStateMixin {
bool _isExpanded = false;
double _bottomPadding = 20.0;
double _menuHeight = 200.0;
late AnimationController _animationController;
late Animation<double> _animation;
@override
void initState() {
super.initState();
_animationController =
AnimationController(vsync: this, duration: Duration(milliseconds: 500));
_animation =
CurvedAnimation(parent: _animationController, curve: Curves.easeInOut);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('flutterfever fab Menu'),
),
body: Center(
child: Text('flutterfever FAB Menu Screen'),
),
floatingActionButton: GestureDetector(
onVerticalDragUpdate: (details) {
setState(() {
_menuHeight -= details.delta.dy;
});
},
onVerticalDragEnd: (details) {
if (_menuHeight < 50.0) {
_isExpanded = false;
_bottomPadding = 20.0;
_menuHeight = 200.0;
_animationController.reverse();
} else {
_isExpanded = true;
_bottomPadding = 100.0;
_animationController.forward();
}
},
child: AnimatedContainer(
duration: Duration(milliseconds: 500),
curve: Curves.easeInOut,
height: _menuHeight,
child: Stack(
children: [
Positioned(
bottom: _bottomPadding,
right: 20.0,
child: ScaleTransition(
scale: _animation,
child: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.edit),
),
),
),
Positioned(
bottom: _bottomPadding,
right: 20.0,
child: ScaleTransition(
scale: _animation,
child: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.camera_alt),
),
),
),
Positioned(
bottom: _bottomPadding,
right: 20.0,
child: FloatingActionButton(
onPressed: () {
if (_isExpanded) {
_isExpanded = false;
_bottomPadding = 20.0;
_menuHeight = 200.0;
_animationController.reverse();
} else {
_isExpanded = true;
_bottomPadding = 100.0;
_menuHeight = 300.0;
_animationController.forward();
}
},
child: Icon(_isExpanded ? Icons.close : Icons.menu),
),
),
],
),
),
),
),
);
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
}
output without draggable:
with draggable screen:
In the code above, we added a GestureDetector widget as the floatingActionButton of the Scaffold widget. Inside the GestureDetector, we added an AnimatedContainer widget to represent the expandable menu. We also defined a _isExpanded variable to keep track of whether the menu is expanded