This commit is contained in:
davmar
2026-08-28 18:23:56 +02:00
commit 0311b8955a
50 changed files with 3120 additions and 0 deletions
+130
View File
@@ -0,0 +1,130 @@
/// First route shown after launch. Hands off to [MainShell] after a short delay.
library;
import 'package:flutter/material.dart';
import '../utils/constants.dart';
import 'main_shell.dart';
/// Branded splash with a fade-in logo. Replaced by the bottom-nav shell.
class SplashScreen extends StatefulWidget {
const SplashScreen({super.key});
@override
State<SplashScreen> createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen>
with SingleTickerProviderStateMixin {
late final AnimationController _controller;
late final Animation<double> _fade;
late final Animation<double> _scale;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 700),
);
_fade = CurvedAnimation(parent: _controller, curve: Curves.easeOut);
_scale = Tween<double>(begin: 0.92, end: 1).animate(
CurvedAnimation(parent: _controller, curve: Curves.easeOutBack),
);
_controller.forward();
_goToShell();
}
Future<void> _goToShell() async {
await Future<void>.delayed(kSplashDuration);
if (!mounted) return;
Navigator.of(context).pushReplacement(
PageRouteBuilder<void>(
pageBuilder: (_, animation, _) => FadeTransition(
opacity: animation,
child: const MainShell(),
),
transitionDuration: const Duration(milliseconds: 400),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final colors = Theme.of(context).colorScheme;
final textTheme = Theme.of(context).textTheme;
return Scaffold(
body: DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
colors.primary,
colors.primaryContainer,
colors.tertiary,
],
),
),
child: SafeArea(
child: FadeTransition(
opacity: _fade,
child: ScaleTransition(
scale: _scale,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 88,
height: 88,
decoration: BoxDecoration(
color: colors.onPrimary.withValues(alpha: 0.16),
borderRadius: BorderRadius.circular(24),
),
child: Icon(
Icons.layers_rounded,
size: 44,
color: colors.onPrimary,
),
),
const SizedBox(height: 24),
Text(
kAppName,
style: textTheme.displaySmall?.copyWith(
color: colors.onPrimary,
),
),
const SizedBox(height: 8),
Text(
'A Material 3 starter template',
style: textTheme.bodyLarge?.copyWith(
color: colors.onPrimary.withValues(alpha: 0.85),
),
),
const SizedBox(height: 40),
SizedBox(
width: 28,
height: 28,
child: CircularProgressIndicator(
strokeWidth: 3,
color: colors.onPrimary,
),
),
],
),
),
),
),
),
),
);
}
}