This repository contains various examples of floating action buttons using the FlutterFloaty
widget in Flutter. The FlutterFloaty
widget allows users to create customizable, draggable, and animated floating buttons.
- Customizable floating buttons
- Smooth animations when dragging
- Different shapes and sizes
- Changeable background colors
- Optional shadow effects
- Accessibility support
- Visibility with
isVisible
property - onHover functionality
- Intrinsic boundaries
A simple floating button with text and rounded corners.
// Set up exact boundaries in which the widget is draggable
final boundaries = Rect.fromLTWH(0, 0, MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height * 0.75,
);
FlutterFloaty(
intrinsicBoundaries: boundaries,
width: 200,
height: 50,
builder: (context) => const Text(
'Flutter Floaty π',
style: TextStyle(color: Colors.white),
),
backgroundColor: Colors.blue,
onDragBackgroundColor: Colors.blueAccent,
borderRadius: 10,
growingFactor: 1.3,
)
A circular button with an icon in the center.
FlutterFloaty(
width: 60,
height: 60,
initialX: 100,
initialY: 300,
builder: (context) => const Icon(
Icons.add,
color: Colors.white,
),
backgroundColor: Colors.green,
onDragBackgroundColor: Colors.greenAccent,
borderRadius: 30,
growingFactor: 1.3,
)
A square-shaped button with text in the center.
FlutterFloaty(
width: 100,
height: 100,
initialX: 200,
initialY: 200,
builder: (context) => const Center(
child: Text(
'Square',
style: TextStyle(color: Colors.white),
),
),
backgroundColor: Colors.red,
onDragBackgroundColor: Colors.redAccent,
borderRadius: 0,
)
A circular button displaying an emoji.
FlutterFloaty(
width: 80,
height: 80,
initialX: 250,
initialY: 400,
builder: (context) => const Center(
child: Text(
'π',
style: TextStyle(fontSize: 32),
),
),
backgroundColor: Colors.purple,
onDragBackgroundColor: Colors.purpleAccent,
borderRadius: 40,
)
A button with a shadow effect.
FlutterFloaty(
width: 150,
height: 50,
initialX: 50,
initialY: 500,
builder: (context) => const Text(
'Shadow Floaty',
style: TextStyle(color: Colors.white),
),
backgroundColor: Colors.orange,
onDragBackgroundColor: Colors.orangeAccent,
borderRadius: 25,
shadow: BoxShadow(
color: Colors.black.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 10,
offset: const Offset(0, 3),
),
)
import 'package:flutter/material.dart';
import 'package:flutter_floaty/flutter_floaty.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
static const backgroundColor = Color(0xFFF1EFE7);
bool isPlaying = false;
double progress = 0;
Duration elapsed = Duration.zero;
final Duration totalDuration = const Duration(minutes: 3);
void togglePlayPause() {
setState(() {
isPlaying = !isPlaying;
});
if (isPlaying) {
_startProgress();
} else {
_stopProgress();
}
}
void _startProgress() {
Future.doWhile(() async {
await Future<void>.delayed(const Duration(seconds: 1));
if (!isPlaying) return false;
setState(() {
elapsed += const Duration(seconds: 1);
progress = elapsed.inSeconds / totalDuration.inSeconds;
});
return elapsed < totalDuration;
});
}
void _stopProgress() {}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: backgroundColor,
appBar: AppBar(
centerTitle: true,
title: const Text('FlutterFloaty Example'),
backgroundColor: backgroundColor,
),
body: Stack(
children: [
// Music Player Control with Progress Bar
FlutterFloaty(
width: 300,
height: 150,
initialX: 50,
initialY: 150,
builder: (context) => Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(
icon: Icon(
isPlaying ? Icons.pause : Icons.play_arrow,
color: Colors.white,
size: 36,
),
onPressed: togglePlayPause,
),
const SizedBox(width: 20),
const Text(
'Now Playing: Flutter Beats',
style: TextStyle(color: Colors.white),
),
],
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: LinearProgressIndicator(
value: progress,
color: Colors.red,
backgroundColor: Colors.grey,
),
),
const SizedBox(height: 8),
Text(
'${elapsed.inMinutes}:${(elapsed.inSeconds % 60).toString().padLeft(2, '0')} / ${totalDuration.inMinutes}:${(totalDuration.inSeconds % 60).toString().padLeft(2, '0')}',
style: const TextStyle(color: Colors.white),
),
],
),
onDragBackgroundColor: Colors.black87,
),
// Picture-in-Picture Video
FlutterFloaty(
width: 200,
height: 150,
initialX: 100,
initialY: 350,
builder: (context) => Container(
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(10),
image: const DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
'https://i3.ytimg.com/vi/erLk59H86ww/maxresdefault.jpg',
),
),
),
child: const Center(
child: Icon(
Icons.play_circle_fill,
color: Colors.white,
size: 50,
),
),
),
onDragBackgroundColor: Colors.black54,
),
FlutterFloaty(
width: 70,
height: 70,
builder: (context) => Container(
decoration: const BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
image: NetworkImage(
'https://avatars.githubusercontent.com/u/9919?s=280&v=4',
),
fit: BoxFit.cover,
),
),
),
backgroundColor: Colors.transparent,
onDragBackgroundColor: Colors.transparent,
borderRadius: 35,
),
FlutterFloaty(
width: 200,
height: 50,
builder: (context) => const Text(
'Flutter Floaty π',
style: TextStyle(color: Colors.white),
),
backgroundColor: Colors.blue,
onDragBackgroundColor: Colors.blueAccent,
),
FlutterFloaty(
width: 100,
height: 100,
initialX: 200,
initialY: 200,
builder: (context) => const Center(
child: Text(
'Square',
style: TextStyle(color: Colors.white),
),
),
backgroundColor: Colors.red,
onDragBackgroundColor: Colors.redAccent,
borderRadius: 0,
),
FlutterFloaty(
width: 60,
height: 60,
initialX: 100,
initialY: 300,
builder: (context) => const Icon(
Icons.add,
color: Colors.white,
),
backgroundColor: Colors.green,
onDragBackgroundColor: Colors.greenAccent,
borderRadius: 30,
),
FlutterFloaty(
width: 70,
height: 70,
builder: (context) => const Icon(
Icons.person,
size: 55,
),
backgroundColor: Colors.transparent,
onDragBackgroundColor: Colors.transparent,
borderRadius: 35,
),
],
),
);
}
}
Here are the parameters used in the FlutterFloaty
widget:
- builder:
WidgetBuilder
- The builder function to display the content within the draggable area. - initialX:
double
- Initial horizontal position of the widget. - initialY:
double
- Initial vertical position of the widget. - width:
double
- Initial width of the widget. - height:
double
- Initial height of the widget. - backgroundColor:
Color
- Initial color of the widget. - onDragBackgroundColor:
Color
- Background color when the widget is being dragged. - borderRadius:
BorderRadius
- Border radius for the container. - growingFactor:
double
- The factor by which the widget grows when dragged. - margin:
EdgeInsetsGeometry?
- Margin for the container. - padding:
EdgeInsetsGeometry?
- Padding for the container. - shape:
BoxShape?
- Shape for the container. - shadow:
BoxShadow?
- Shadow for the container. - scale:
double
- Scale for the Transform.scale widget. - onTap:
VoidCallback?
- Callback when the widget is tapped. - onHover:
VoidCallback?
- Callback when the user hovers with mouse. - isVisible:
bool?
- To hide and show the widget based on state. - intrinsicBoundaries:
Rect?
- To determine the boundaries in which the widget is draggable - enableAnimation:
bool?
- To enable the growing effect on Widget drag. - onPausePlaceHolder:
Widget?
- Placeholder widget builder to show when the drag ends.
-
Clone the repository:
git clone https://github.com/jordyhers/flutter_floaty.git
-
Navigate to the project directory:
cd flutter_floaty
-
Install dependencies:
flutter pub get
-
Run the project:
flutter run
Contributions are welcome! Feel free to submit a pull request or open an issue.
This project is licensed under the MIT License. See the LICENSE file for more details.
Very Good Flutter Plugin uses [fluttium][fluttium_link] for integration tests. Those tests are located
in the front facing package flutter_floaty
example.
β In order to run the integration tests, you need to have the fluttium_cli
installed. [See how][fluttium_install].
To run the integration tests, run the following command from the root of the project:
cd flutter_floaty/example
fluttium test flows/test_platform_name.yaml