water_drop_progress 1.0.0
water_drop_progress: ^1.0.0 copied to clipboard
A customizable animated water-drop progress indicator with smooth liquid waves and animated fill levels.
Water Drop Progress #
A customizable animated water-drop progress indicator for Flutter.
Use it to display hydration levels, water tank levels, upload progress, download progress, goal completion, and other percentage-based values with a smooth liquid-wave animation.
Preview #
[Water Drop Progress Demo]
Features #
- Animated water level
- Smooth wave movement
- Custom gradients
- Percentage display
- Custom overlay content
- Smooth progress transitions
- Configurable wave amplitude and wavelength
- Custom border and shadow styles
- Custom empty-drop background
- Optional percentage formatter
- Accessibility support
- No third-party runtime dependencies
- Works with any state-management solution
Installation #
Add the package to your pubspec.yaml:
dependencies:
water_drop_progress: ^1.0.0
Then run:
flutter pub get
Import #
import 'package:water_drop_progress/water_drop_progress.dart';
Basic Usage #
WaterDropProgress(
value: 0.50,
width: 160,
height: 180,
)
The value represents progress between 0.0 and 1.0:
0.0 // Empty
0.5 // 50%
1.0 // Full
Values lower than 0.0 or greater than 1.0 are automatically clamped.
Hydration Tracker Example #
final int consumed = 1250;
final int dailyGoal = 2500;
final double progress = dailyGoal > 0
? (consumed / dailyGoal).clamp(0.0, 1.0)
: 0.0;
Use the calculated progress:
WaterDropProgress(
value: progress,
width: 160,
height: 180,
)
Show Custom Content #
When child is provided, it replaces the default percentage text.
WaterDropProgress(
value: progress,
width: 160,
height: 180,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'$consumed mL',
style: const TextStyle(
color: Colors.white,
fontSize: 22,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 4),
Text(
'of $dailyGoal mL',
style: const TextStyle(
color: Colors.white,
fontSize: 12,
),
),
],
),
)
Custom Gradient #
WaterDropProgress(
value: 0.70,
waterGradient: const LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xFF74EBD5),
Color(0xFF35B7C9),
Color(0xFF147D92),
],
),
)
Disable Wave Animation #
WaterDropProgress(
value: 0.60,
animateWave: false,
)
Disable Level Animation #
WaterDropProgress(
value: 0.60,
animateLevel: false,
)
Hide Percentage #
WaterDropProgress(
value: 0.60,
showPercentage: false,
)
Customize Percentage Style #
WaterDropProgress(
value: 0.75,
percentageStyle: const TextStyle(
color: Colors.white,
fontSize: 28,
fontWeight: FontWeight.w800,
),
)
Customize Percentage Text #
WaterDropProgress(
value: 0.75,
percentageFormatter: (value) {
return '${(value * 2500).round()} mL';
},
)
Customize Wave #
WaterDropProgress(
value: 0.65,
waveAmplitude: 0.05,
waveLength: 0.90,
waveAnimationDuration: const Duration(
milliseconds: 1400,
),
)
Customize Level Animation #
WaterDropProgress(
value: 0.80,
levelAnimationDuration: const Duration(
milliseconds: 900,
),
levelCurve: Curves.easeInOutCubic,
)
Customize Border and Background #
WaterDropProgress(
value: 0.75,
emptyColor: const Color(0xFFF5F7FA),
borderColor: const Color(0xFFE7EAF0),
innerBorderColor: const Color(0xFFD9DEE8),
borderWidth: 8,
innerBorderWidth: 3,
)
Customize Shadow #
WaterDropProgress(
value: 0.65,
shadowColor: Colors.black26,
shadowElevation: 12,
)
Accessibility #
WaterDropProgress(
value: 0.60,
semanticLabel: 'Daily hydration progress',
)
Animation Completion Callback #
WaterDropProgress(
value: 0.85,
onLevelAnimationEnd: () {
debugPrint('Water level animation completed');
},
)
Complete Example #
import 'package:flutter/material.dart';
import 'package:water_drop_progress/water_drop_progress.dart';
void main() {
runApp(const ExampleApp());
}
class ExampleApp extends StatelessWidget {
const ExampleApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: WaterDropExampleScreen(),
);
}
}
class WaterDropExampleScreen extends StatefulWidget {
const WaterDropExampleScreen({super.key});
@override
State<WaterDropExampleScreen> createState() {
return _WaterDropExampleScreenState();
}
}
class _WaterDropExampleScreenState
extends State<WaterDropExampleScreen> {
double progress = 0.50;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Water Drop Progress'),
centerTitle: true,
),
body: SafeArea(
child: Center(
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
WaterDropProgress(
value: progress,
width: 170,
height: 200,
),
const SizedBox(height: 24),
Text(
'${(progress * 2500).round()} mL',
style: const TextStyle(
fontSize: 24,
fontWeight: FontWeight.w800,
),
),
const SizedBox(height: 4),
const Text(
'Daily goal: 2500 mL',
),
const SizedBox(height: 24),
Slider(
value: progress,
min: 0,
max: 1,
divisions: 100,
label: '${(progress * 100).round()}%',
onChanged: (double value) {
setState(() {
progress = value;
});
},
),
],
),
),
),
),
);
}
}
Main Parameters #
| Parameter | Type | Default | Description |
|---|---|---|---|
value |
double |
Required | Progress value from 0.0 to 1.0 |
width |
double |
160 |
Drop width |
height |
double |
180 |
Drop height |
animateLevel |
bool |
true |
Animates water-level changes |
animateWave |
bool |
true |
Enables continuous wave movement |
levelAnimationDuration |
Duration |
700ms |
Duration of water-level animation |
waveAnimationDuration |
Duration |
1600ms |
Duration of one wave cycle |
levelCurve |
Curve |
easeInOutCubic |
Curve used for level changes |
waveAmplitude |
double |
0.04 |
Wave height relative to drop height |
waveLength |
double |
0.85 |
Wave length relative to drop width |
waterGradient |
Gradient |
Blue gradient | Water fill gradient |
emptyColor |
Color |
Light grey | Empty-drop background |
borderColor |
Color |
Light grey | Outer border color |
innerBorderColor |
Color |
Light grey | Inner border color |
borderWidth |
double |
8 |
Outer border width |
innerBorderWidth |
double |
3 |
Inner border width |
shadowColor |
Color |
Transparent black | Drop shadow color |
shadowElevation |
double |
10 |
Drop shadow elevation |
showPercentage |
bool |
true |
Displays percentage text |
percentageStyle |
TextStyle? |
null |
Custom percentage style |
percentageFormatter |
String Function(double)? |
null |
Custom percentage formatter |
child |
Widget? |
null |
Custom content inside the drop |
semanticLabel |
String? |
null |
Accessibility label |
onLevelAnimationEnd |
VoidCallback? |
null |
Called when level animation finishes |
Use Cases #
- Hydration trackers
- Water-consumption applications
- Water tank indicators
- Goal-completion widgets
- Upload progress
- Download progress
- Fitness and health applications
- Environmental dashboards
- Smart-home water monitoring
- Onboarding and loading screens
Performance #
The widget uses CustomPainter, AnimationController, and RepaintBoundary to keep animations smooth and minimize unnecessary rebuilds.
For best performance:
- Avoid using very large widget dimensions.
- Disable
animateWavewhen the widget is not visible. - Reuse the same widget instead of recreating it unnecessarily.
- Keep custom overlay widgets lightweight.
Contributing #
Contributions are welcome.
You can contribute by:
- Reporting bugs
- Suggesting features
- Improving documentation
- Adding tests
- Submitting pull requests
For major changes, open an issue first to discuss the proposed update.
Issues and Feedback #
Found a bug or have a feature request? Open an issue in the package repository.
License #
This project is licensed under the MIT License.
See the LICENSE file for complete license information.