Build a Futuristic Wireless Power Share Tracker App in Flutter (Single main.dart)
Demo :
Click Video πππ
⭐ FEATURES :
-
Single
main.dartfile -
Cyberpunk grid background
-
Animated energy flow
-
Efficiency meter
-
Responsive (Mobile / Tablet / Desktop)
-
Perfect for Flutter UI portfolio
Code :
import 'dart:async';
import 'dart:math';
import 'dart:ui';
import 'package:flutter/material.dart';
void main() {
runApp(const PowerShareApp());
}
class PowerShareApp extends StatelessWidget {
const PowerShareApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Power Share',
theme: ThemeData(
brightness: Brightness.dark,
scaffoldBackgroundColor: const Color(0xFF050510),
primaryColor: const Color(0xFF00F0FF), // Neon Cyan
colorScheme: const ColorScheme.dark(
primary: Color(0xFF00F0FF),
secondary: Color(0xFFBD00FF), // Neon Purple
surface: Color(0xFF101020),
),
fontFamily: 'Courier', // Tech-like font
textTheme: const TextTheme(
displayLarge: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
bodyLarge: TextStyle(color: Color(0xFFAAAAAA)),
),
),
home: const PowerShareScreen(),
);
}
}
class PowerShareScreen extends StatefulWidget {
const PowerShareScreen({super.key});
@override
State<PowerShareScreen> createState() => _PowerShareScreenState();
}
class _PowerShareScreenState extends State<PowerShareScreen> with SingleTickerProviderStateMixin {
// State variables
bool _isGiver = true;
double _batteryLevel = 0.85;
double _efficiency = 0.92;
Timer? _simulationTimer;
late AnimationController _flowController;
final Random _random = Random();
@override
void initState() {
super.initState();
// Animation for energy flow
_flowController = AnimationController(
vsync: this,
duration: const Duration(seconds: 2),
)..repeat();
// Start simulation
_startSimulation();
}
void _startSimulation() {
_simulationTimer = Timer.periodic(const Duration(seconds: 2), (timer) {
setState(() {
// Toggle role occasionally to demo both states
if (_random.nextInt(10) > 8) {
_isGiver = !_isGiver;
}
// Simulate battery changes
if (_isGiver) {
_batteryLevel -= 0.01;
if (_batteryLevel < 0.1) _batteryLevel = 1.0;
} else {
_batteryLevel += 0.01;
if (_batteryLevel > 1.0) _batteryLevel = 0.2;
}
// Clamp battery
_batteryLevel = _batteryLevel.clamp(0.0, 1.0);
// Efficiency fluctuation
_efficiency = 0.85 + (_random.nextDouble() * 0.14); // 85% - 99%
});
});
}
@override
void dispose() {
_simulationTimer?.cancel();
_flowController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final isDesktop = MediaQuery.of(context).size.width > 800;
return Scaffold(
body: Stack(
children: [
// Background Grid
Positioned.fill(child: const CyberGridBackground()),
SafeArea(
child: Center(
child: LayoutBuilder(
builder: (context, constraints) {
return SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_buildHeader(),
const SizedBox(height: 40),
if (isDesktop)
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
_buildRoleCard(isGiver: _isGiver),
Expanded(child: _buildEnergyFlow()),
_buildStatsCard(),
],
)
else
Column(
children: [
_buildRoleCard(isGiver: _isGiver),
SizedBox(height: 40, child: _buildEnergyFlow(vertical: true)),
_buildStatsCard(),
],
),
const SizedBox(height: 40),
_buildEfficiencyMeter(),
],
),
),
);
},
),
),
),
],
),
);
}
Widget _buildHeader() {
return Column(
children: [
Text(
"POWER LINK v2.0",
style: TextStyle(
color: Theme.of(context).primaryColor,
fontSize: 24,
letterSpacing: 4,
shadows: [
Shadow(color: Theme.of(context).primaryColor, blurRadius: 10),
],
),
),
const SizedBox(height: 8),
Text(
_isGiver ? "TRANSMITTING ENERGY..." : "RECEIVING ENERGY...",
style: const TextStyle(
color: Colors.white70,
fontSize: 14,
letterSpacing: 2,
),
),
],
);
}
Widget _buildRoleCard({required bool isGiver}) {
final color = isGiver ? Theme.of(context).primaryColor : Theme.of(context).colorScheme.secondary;
return Container(
width: 250,
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
color: const Color(0xFF101020).withOpacity(0.9),
borderRadius: BorderRadius.circular(20),
border: Border.all(color: color.withOpacity(0.5), width: 1),
boxShadow: [
BoxShadow(color: color.withOpacity(0.2), blurRadius: 20, spreadRadius: 2),
],
),
child: Column(
children: [
Icon(
isGiver ? Icons.bolt : Icons.battery_charging_full,
size: 60,
color: color,
),
const SizedBox(height: 20),
Text(
isGiver ? "HOST" : "CLIENT",
style: TextStyle(color: color, fontSize: 28, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
Text(
"${(_batteryLevel * 100).toInt()}%",
style: const TextStyle(
color: Colors.white,
fontSize: 48,
fontWeight: FontWeight.bold,
),
),
LinearProgressIndicator(
value: _batteryLevel,
backgroundColor: Colors.grey[800],
color: color,
minHeight: 8,
),
],
),
);
}
Widget _buildEnergyFlow({bool vertical = false}) {
return AnimatedBuilder(
animation: _flowController,
builder: (context, child) {
return CustomPaint(
size: vertical ? const Size(50, 150) : const Size(300, 50),
painter: FlowPainter(
animationValue: _flowController.value,
color: Theme.of(context).primaryColor, // Giver color logic usually
isVertical: vertical,
),
);
},
);
}
Widget _buildStatsCard() {
return Container(
width: 250,
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
color: const Color(0xFF101020).withOpacity(0.9),
borderRadius: BorderRadius.circular(20),
border: Border.all(color: Colors.white10),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildStatRow("VOLTAGE", "9.0 V"),
const SizedBox(height: 16),
_buildStatRow("CURRENT", "1.5 A"),
const SizedBox(height: 16),
_buildStatRow("TEMP", "36.5°C"),
const SizedBox(height: 16),
_buildStatRow("STATUS", "ACTIVE", valueColor: Colors.greenAccent),
],
),
);
}
Widget _buildStatRow(String label, String value, {Color? valueColor}) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(label, style: const TextStyle(color: Colors.grey, fontSize: 12)),
Text(
value,
style: TextStyle(
color: valueColor ?? Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
],
);
}
Widget _buildEfficiencyMeter() {
return Column(
children: [
const Text("TRANSFER EFFICIENCY", style: TextStyle(color: Colors.grey, letterSpacing: 2)),
const SizedBox(height: 16),
Container(
height: 30, // Thicker bar
width: 300,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.grey[900],
border: Border.all(color: Colors.white24),
),
child: Stack(
children: [
LayoutBuilder(
builder: (context, constraints) {
return Container(
width: constraints.maxWidth * _efficiency,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
gradient: LinearGradient(
colors: [Colors.blue.shade900, Theme.of(context).colorScheme.secondary],
),
boxShadow: [
BoxShadow(
color: Theme.of(context).colorScheme.secondary.withOpacity(0.5),
blurRadius: 10,
)
]
),
);
}
),
Center(
child: Text(
"${(_efficiency * 100).toStringAsFixed(1)}%",
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
shadows: [Shadow(color: Colors.black, blurRadius: 2)],
),
),
),
],
),
),
],
);
}
}
class FlowPainter extends CustomPainter {
final double animationValue;
final Color color;
final bool isVertical;
FlowPainter({required this.animationValue, required this.color, required this.isVertical});
@override
void paint(Canvas canvas, Size size) {
final Paint paint = Paint()
..style = PaintingStyle.fill
..shader = LinearGradient(
colors: [color.withOpacity(0.0), color, color.withOpacity(0.0)],
stops: const [0.0, 0.5, 1.0],
transform: GradientRotation(animationValue * 2 * pi),
).createShader(Rect.fromLTWH(0, 0, size.width, size.height));
// Draw multiple flowing particles/lines representing energy
final count = 5;
final spacing = isVertical ? size.height / count : size.width / count;
for (int i = 0; i < count; i++) {
double offset = (animationValue * spacing * count + i * spacing) % (isVertical ? size.height : size.width);
if (isVertical) {
canvas.drawCircle(Offset(size.width / 2, offset), 4, Paint()..color = color.withOpacity(0.6)..maskFilter = const MaskFilter.blur(BlurStyle.normal, 3));
} else {
canvas.drawCircle(Offset(offset, size.height / 2), 4, Paint()..color = color.withOpacity(0.6)..maskFilter = const MaskFilter.blur(BlurStyle.normal, 3));
}
}
// Draw main connection line with glow
final linePaint = Paint()
..color = color.withOpacity(0.3)
..strokeWidth = 2
..style = PaintingStyle.stroke;
if (isVertical) {
canvas.drawLine(Offset(size.width/2, 0), Offset(size.width/2, size.height), linePaint);
} else {
canvas.drawLine(Offset(0, size.height/2), Offset(size.width, size.height/2), linePaint);
}
}
@override
bool shouldRepaint(FlowPainter oldDelegate) => true;
}
class CyberGridBackground extends StatelessWidget {
const CyberGridBackground({super.key});
@override
Widget build(BuildContext context) {
return CustomPaint(
painter: GridPainter(),
);
}
}
class GridPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final Paint paint = Paint()
..color = Colors.white.withOpacity(0.05)
..style = PaintingStyle.stroke
..strokeWidth = 1;
const double step = 40;
for (double x = 0; x < size.width; x += step) {
canvas.drawLine(Offset(x, 0), Offset(x, size.height), paint);
}
for (double y = 0; y < size.height; y += step) {
canvas.drawLine(Offset(0, y), Offset(size.width, y), paint);
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
Comments
Post a Comment