Skip to content

Commit

Permalink
Merge pull request #60 from nimblehq/feature/54-ui-skeleton-loading-a…
Browse files Browse the repository at this point in the history
…nimation

[#54] [UI] As a logged in user, I can see skeleton loading animation
  • Loading branch information
nkhanh44 authored Aug 18, 2023
2 parents 23c3c80 + 5e75bd4 commit dd86778
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 12 deletions.
61 changes: 49 additions & 12 deletions lib/screens/home/home_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,63 @@ import 'package:flutter/material.dart';
import 'package:survey_flutter/screens/home/home_header_widget.dart';
import 'package:survey_flutter/screens/home/home_pages_widget.dart';
import 'package:survey_flutter/screens/home/home_page_indicator_widget.dart';
import 'package:survey_flutter/screens/home/home_shimmer_loading.dart';

const routePathHomeScreen = '/home';

class HomeScreen extends StatelessWidget {
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);

@override
State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
bool _isLoading = true;

@override
void initState() {
super.initState();
_openHomeWithShimmerLoading();
}

Future<void> _openHomeWithShimmerLoading() async {
await Future.delayed(const Duration(seconds: 1));
setState(() {
_isLoading = false;
});
}

@override
Widget build(BuildContext context) {
return Stack(
children: [
HomePagesWidget(),
const HomeHeaderWidget(),
const Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: EdgeInsets.only(bottom: 220),
child: HomePageIndicatorWidget(),
return Scaffold(
body: Stack(
children: [
HomePagesWidget(),
const HomeHeaderWidget(),
const Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: EdgeInsets.only(bottom: 220),
child: HomePageIndicatorWidget(),
),
),
),
],
// TODO: Handle only show shimmer loading after user login
if (_isLoading) _buildShimmerLoading(),
],
),
);
}

Widget _buildShimmerLoading() {
return AnimatedOpacity(
opacity: 1.0,
duration: const Duration(seconds: 1),
curve: Curves.easeInOut,
child: Container(
color: Colors.black,
child: const HomeShimmerLoading(),
),
);
}
}
113 changes: 113 additions & 0 deletions lib/screens/home/home_shimmer_loading.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import 'package:flutter/material.dart';
import 'package:shimmer/shimmer.dart';
import 'package:survey_flutter/theme/app_constants.dart';

const double _bottomPadding = 62;
const double _rectangleHeight = 20;
const double _circleSize = 36;

class HomeShimmerLoading extends StatelessWidget {
const HomeShimmerLoading({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
final screenWidth = MediaQuery.sizeOf(context).width;

return Shimmer.fromColors(
baseColor: Colors.white.withOpacity(0.12),
highlightColor: Colors.white24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildTopRows(screenWidth),
const Spacer(),
_buildBottomRows(screenWidth),
],
),
);
}

Widget _buildTopRows(double screenWidth) {
return Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildShimmerText(
topPadding: 61,
width: screenWidth * 0.3,
),
_buildShimmerText(
topPadding: 10,
width: screenWidth * 0.25,
),
],
),
const Spacer(),
Padding(
padding: const EdgeInsets.only(top: 79, right: Metrics.spacing20),
child: Container(
width: _circleSize,
height: _circleSize,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.black,
),
),
),
],
);
}

Widget _buildShimmerText({
double? topPadding,
double? bottomPadding,
double? width,
}) {
return Padding(
padding: EdgeInsets.only(
left: Metrics.spacing20,
top: topPadding ?? 0,
right: Metrics.spacing20,
bottom: bottomPadding ?? 0,
),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(_rectangleHeight / 2),
color: Colors.black,
),
width: width,
height: _rectangleHeight,
),
);
}

Widget _buildBottomRows(double screenWidth) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildShimmerText(
topPadding: 0,
width: screenWidth * 0.1,
),
_buildShimmerText(
topPadding: Metrics.spacing16,
width: screenWidth * 0.67,
),
_buildShimmerText(
topPadding: Metrics.spacing10,
width: screenWidth * 0.3,
),
_buildShimmerText(
topPadding: Metrics.spacing16,
width: screenWidth * 0.84,
),
_buildShimmerText(
topPadding: Metrics.spacing10,
bottomPadding: _bottomPadding,
width: screenWidth * 0.5,
),
],
);
}
}
1 change: 1 addition & 0 deletions lib/theme/app_constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ class Metrics {
static const formFieldHeight = 56.0;

static const spacing4 = 4.0;
static const spacing10 = 10.0;
static const spacing16 = 16.0;
static const spacing20 = 20.0;
static const spacing28 = 28.0;
Expand Down
8 changes: 8 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.4"
shimmer:
dependency: "direct main"
description:
name: shimmer
sha256: "5f88c883a22e9f9f299e5ba0e4f7e6054857224976a5d9f839d4ebdc94a14ac9"
url: "https://pub.dev"
source: hosted
version: "3.0.0"
sky_engine:
dependency: transitive
description: flutter
Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ dependencies:
internet_connection_checker: ^1.0.0+1
page_view_dot_indicator: ^2.1.0
flutter_secure_storage: ^8.0.0
shimmer: ^3.0.0

dev_dependencies:
build_runner: ^2.4.4
Expand Down

0 comments on commit dd86778

Please sign in to comment.