From d36348c59c1b87afbdf4f1e7f065dff86aa0a301 Mon Sep 17 00:00:00 2001 From: mathiskirchner Date: Sat, 15 Nov 2025 21:24:52 +0100 Subject: [PATCH] added skeleton loading --- .../views/main_menu/groups_view.dart | 65 ++++++++++++++----- lib/presentation/widgets/group_tile.dart | 2 +- 2 files changed, 48 insertions(+), 19 deletions(-) diff --git a/lib/presentation/views/main_menu/groups_view.dart b/lib/presentation/views/main_menu/groups_view.dart index 76034a6..e52cf58 100644 --- a/lib/presentation/views/main_menu/groups_view.dart +++ b/lib/presentation/views/main_menu/groups_view.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:game_tracker/presentation/widgets/full_width_button.dart'; import 'package:game_tracker/presentation/widgets/group_tile.dart'; import 'package:game_tracker/presentation/widgets/top_centered_message.dart'; +import 'package:skeletonizer/skeletonizer.dart'; class Group { final String id; @@ -29,7 +30,7 @@ class GroupsView extends StatefulWidget { class _GroupsViewState extends State { Future> _getMockGroups() async { - await Future.delayed(const Duration(seconds: 1)); + await Future.delayed(const Duration(seconds: 4)); final player1 = Player(id: 'p1', name: 'Felix'); final player2 = Player(id: 'p2', name: 'Yannick'); final player3 = Player(id: 'p3', name: 'Mathis'); @@ -88,45 +89,73 @@ class _GroupsViewState extends State { ]; } + final player = Player(id: 'p1', name: 'Felix'); + late final List skeletonData = List.filled( + 7, + Group( + id: 'g1', + name: 'Weekend Warriors', + members: [player, player, player, player], + ), + ); + @override Widget build(BuildContext context) { return SafeArea( child: Stack( children: [ - FutureBuilder( + FutureBuilder>( future: _getMockGroups(), builder: (BuildContext context, AsyncSnapshot> snapshot) { - if (snapshot.connectionState == ConnectionState.waiting) { - return const Center( - child: TopCenteredMessage( - message: 'Data not yet available, show sceleton', - ), - ); - } else if (snapshot.hasError) { + if (snapshot.hasError) { return const Center( child: TopCenteredMessage( message: 'Error while loading group data.', ), ); - } else if (!snapshot.hasData || snapshot.data!.isEmpty) { + } + if (snapshot.connectionState == ConnectionState.done && + (!snapshot.hasData || snapshot.data!.isEmpty)) { return const Center( child: TopCenteredMessage( message: 'No groups created yet.', ), ); } - //return Center(child: Text('whatever')); - //return GroupTile(group: snapshot.data![0]); - return ListView.builder( - padding: const EdgeInsets.only(bottom: 85), - itemCount: snapshot.data!.length, - itemBuilder: (BuildContext context, int index) { - return GroupTile(group: snapshot.data![index]); - }, + final bool isLoading = + snapshot.connectionState == ConnectionState.waiting; + final List groups = isLoading + ? skeletonData + : (snapshot.data ?? []); + return Skeletonizer( + effect: PulseEffect( + from: Colors.grey[100]!, + to: Colors.grey[400]!, + duration: const Duration(milliseconds: 800), + ), + enabled: isLoading, + enableSwitchAnimation: true, + switchAnimationConfig: const SwitchAnimationConfig( + duration: Duration(milliseconds: 200), + switchInCurve: Curves.linear, + switchOutCurve: Curves.linear, + transitionBuilder: + AnimatedSwitcher.defaultTransitionBuilder, + layoutBuilder: AnimatedSwitcher.defaultLayoutBuilder, + ), + child: ListView.builder( + padding: const EdgeInsets.only(bottom: 85), + itemCount: groups.length, + itemBuilder: (BuildContext context, int index) { + return GroupTile(group: groups[index]); + }, + ), ); }, ), + + // Dein Button bleibt wie gehabt Positioned( bottom: 16, right: 16, diff --git a/lib/presentation/widgets/group_tile.dart b/lib/presentation/widgets/group_tile.dart index 783abcd..87d997b 100644 --- a/lib/presentation/widgets/group_tile.dart +++ b/lib/presentation/widgets/group_tile.dart @@ -59,7 +59,7 @@ class GroupTile extends StatelessWidget { horizontal: 10, ), decoration: BoxDecoration( - color: Colors.black26, + color: Colors.black38, borderRadius: BorderRadius.circular(12), ), child: Text(