Ever wondered how to harness the power of AI to create beautiful images directly from your mobile app? Today, I'll walk you through building FluxGen - a modern Flutter application that transforms text prompts into stunning visuals using AI!
🌟 What We're Building
FluxGen is more than just another AI app - it's a complete creative toolkit featuring:
- 🎯 6 Different AI Models (Flux Pro, Realism, Anime Style, 3D Render, etc.)
- 📱 Cross-platform support (Android, iOS, Desktop)
- 🎨 Modern Glass-morphism UI with smooth animations
- 💾 Smart download system with proper permissions
- ⚡ Lightning-fast generation with fallback options
🏗️ Architecture Overview
The app follows a clean, maintainable architecture:
class _ImageGeneratorScreenState extends State<ImageGeneratorScreen>
with TickerProviderStateMixin {
// Core state management
final TextEditingController _promptController = TextEditingController();
String? _generatedImageUrl;
bool _isLoading = false;
String _selectedModel = 'flux';
String _selectedSize = '1024x1024';
// Animation controllers for smooth UX
late AnimationController _animationController;
late AnimationController _pulseController;
}
🚀 Key Implementation Highlights
1. AI Integration with Pollinations API
The magic happens with a simple HTTP request to the free Pollinations AI API:
Future<void> _generateImage() async {
if (_promptController.text.trim().isEmpty) {
_showSnackBar('Please enter a prompt', const Color(0xFFFF6B6B));
return;
}
setState(() {
_isLoading = true;
_generatedImageUrl = null;
});
try {
final encodedPrompt = Uri.encodeComponent(_promptController.text.trim());
final dimensions = _selectedSize.split('x');
final url = 'https://image.pollinations.ai/prompt/$encodedPrompt'
'?model=$_selectedModel'
'&width=${dimensions[0]}'
'&height=${dimensions[1]}'
'&enhance=true'
'&nologo=true'
'&seed=${DateTime.now().millisecondsSinceEpoch}';
final response = await http.get(Uri.parse(url)).timeout(
const Duration(seconds: 30)
);
if (response.statusCode == 200) {
setState(() {
_generatedImageUrl = url;
_isLoading = false;
});
_animationController.forward();
}
} catch (e) {
// Fallback logic here
}
}
2. Cross-Platform File Downloads
Handling downloads across different platforms was tricky, but here's how I solved it:
Future<void> _downloadImage() async {
if (_generatedImageUrl == null) return;
setState(() => _isDownloading = true);
try {
if (Platform.isAndroid) {
// Handle Android permissions based on API level
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
Permission permission;
if (androidInfo.version.sdkInt >= 33) {
permission = Permission.photos;
} else if (androidInfo.version.sdkInt >= 30) {
permission = Permission.manageExternalStorage;
} else {
permission = Permission.storage;
}
var status = await permission.status;
if (!status.isGranted) {
status = await permission.request();
}
// Download and save logic...
}
} catch (e) {
_showSnackBar('Error: ${e.toString()}', Colors.red);
}
}
3. Responsive Glass-Morphism UI
Creating that modern, glassmorphic look:
Widget _buildGlassCard({required Widget child, double? height}) {
return Container(
height: height,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24),
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Colors.white.withValues(alpha: 0.8),
Colors.white.withValues(alpha: 0.4),
],
),
border: Border.all(
color: Colors.white.withValues(alpha: 0.3),
width: 1,
),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.1),
blurRadius: 20,
offset: const Offset(0, 8),
),
],
),
child: child,
);
}
4. Smooth Animations
Adding life to the UI with meaningful animations:
@override
void initState() {
super.initState();
_animationController = AnimationController(
duration: const Duration(milliseconds: 800),
vsync: this,
);
_fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
CurvedAnimation(
parent: _animationController,
curve: Curves.easeOutCubic
),
);
_scaleAnimation = Tween<double>(begin: 0.8, end: 1.0).animate(
CurvedAnimation(
parent: _animationController,
curve: Curves.elasticOut
),
);
}
🎯 Smart Features That Make the Difference
Quick Prompt Suggestions
Instead of letting users stare at a blank text field, I added contextual suggestions:
final List<Map<String, dynamic>> _promptSuggestions = [
{
'text': 'Cyberpunk neon city',
'icon': Icons.location_city,
'color': Color(0xFF00D4FF)
},
{
'text': 'Majestic dragon',
'icon': Icons.pets,
'color': Color(0xFFFF6B6B)
},
// More suggestions...
];
Responsive Design
The app adapts beautifully to different screen sizes:
Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
final isSmallScreen = screenWidth < 600;
return isSmallScreen
? Column(children: [...]) // Mobile layout
: Row(children: [...]); // Tablet/desktop layout
}
📱 The Result
Here's what makes FluxGen special:
- 🎨 Multiple AI Models: Users can choose from Flux Pro, Realism, Anime Style, 3D Render, and more
- 📏 Flexible Sizing: Support for various resolutions from 512×512 to 1920×1080
- 💡 Smart UX: Loading states, error handling, and intuitive feedback
- ⚡ Performance: Efficient image loading with fallback options
- 🎭 Beautiful UI: Modern design that users love to interact with
🚦 Challenges & Solutions
Challenge 1: Android Storage Permissions
Problem: Android's ever-changing permission model across API levels.
Solution: Dynamic permission handling based on Android version detection.
Challenge 2: Image Loading States
Problem: Users needed feedback during generation.
Solution: Created engaging loading animations with SpinKit and progress indicators.
Challenge 3: Cross-Platform Downloads
Problem: Different platforms handle file storage differently.
Solution: Platform-specific logic with proper fallbacks.
🔧 Dependencies Used
dependencies:
flutter:
sdk: flutter
http: ^1.1.0 # API calls
flutter_spinkit: ^5.2.0 # Loading animations
path_provider: ^2.1.1 # File system access
permission_handler: ^11.0.1 # Permissions
device_info_plus: ^10.1.0 # Device info
📊 Performance Tips
-
Image Caching: Use
cached_network_image
for better performance - Lazy Loading: Load images only when needed
- Memory Management: Dispose controllers properly
- Error Boundaries: Always have fallback options
🎉 What's Next?
Future improvements planned:
- 🔄 Image editing capabilities
- 📚 History/favorites system
- 🎨 Custom model training
- 🌐 Social sharing features
- 💾 Cloud storage integration
🤝 Open Source & Community
The entire project is open source! Check it out on GitHub and feel free to:
- ⭐ Star the repo
- 🐛 Report issues
- 🚀 Submit PRs
- 💡 Suggest features
🎯 Key Takeaways
Building FluxGen taught me:
- User Experience First: Beautiful UI means nothing without smooth functionality
- Handle Edge Cases: Always plan for network failures, permission denials, etc.
- Performance Matters: Optimize for both fast and slow devices
- Cross-Platform Complexity: Each platform has its quirks - embrace them
- Iterate Based on Feedback: The best apps evolve with user needs
📚 Resources & Links
- GitHub Repository: Fluxgen
- Pollinations AI: AI Image Generation
📞 Get Involved
Want to contribute or have questions?
- 💬 Join the discussion in the issues
- 🔄 Fork and create your own version
- 📧 Reach out with feedback
What would you add to an AI image generator? Drop your ideas in the comments! 👇
If this helped you, consider giving the repo a ⭐ - it means the world to indie developers like me!