From 138640d47d7b140206e9fbb3a9102ffc53630fde Mon Sep 17 00:00:00 2001 From: efrilm Date: Tue, 12 Aug 2025 23:43:07 +0700 Subject: [PATCH] feat: update home page --- lib/presentation/pages/home/home_page.dart | 156 ++++++++------------- 1 file changed, 59 insertions(+), 97 deletions(-) diff --git a/lib/presentation/pages/home/home_page.dart b/lib/presentation/pages/home/home_page.dart index 82d7e74..a314379 100644 --- a/lib/presentation/pages/home/home_page.dart +++ b/lib/presentation/pages/home/home_page.dart @@ -21,21 +21,12 @@ class HomePage extends StatefulWidget { } class _HomePageState extends State with TickerProviderStateMixin { - late ScrollController _scrollController; late AnimationController _headerAnimationController; late AnimationController _contentAnimationController; - late AnimationController _appBarAnimationController; - - late Animation _appBarOpacityAnimation; - late Animation _appBarSlideAnimation; - - bool _showAppBar = false; @override void initState() { super.initState(); - _scrollController = ScrollController(); - _scrollController.addListener(_scrollListener); _headerAnimationController = AnimationController( duration: const Duration(milliseconds: 800), @@ -47,28 +38,6 @@ class _HomePageState extends State with TickerProviderStateMixin { vsync: this, ); - // AppBar Animation Controller - _appBarAnimationController = AnimationController( - duration: const Duration(milliseconds: 300), - vsync: this, - ); - - // AppBar Animations - _appBarOpacityAnimation = Tween(begin: 0.0, end: 1.0).animate( - CurvedAnimation( - parent: _appBarAnimationController, - curve: Curves.easeInOut, - ), - ); - - _appBarSlideAnimation = - Tween(begin: const Offset(0.0, -1.0), end: Offset.zero).animate( - CurvedAnimation( - parent: _appBarAnimationController, - curve: Curves.easeOutCubic, - ), - ); - _startAnimations(); } @@ -79,86 +48,79 @@ class _HomePageState extends State with TickerProviderStateMixin { }); } - void _scrollListener() { - const double threshold = 200.0; - - if (_scrollController.offset > threshold && !_showAppBar) { - setState(() { - _showAppBar = true; - }); - _appBarAnimationController.forward(); - } else if (_scrollController.offset <= threshold && _showAppBar) { - _appBarAnimationController.reverse().then((_) { - if (mounted) { - setState(() { - _showAppBar = false; - }); - } - }); - } - } - @override void dispose() { - _scrollController.removeListener(_scrollListener); - _scrollController.dispose(); _headerAnimationController.dispose(); _contentAnimationController.dispose(); - _appBarAnimationController.dispose(); super.dispose(); } - PreferredSizeWidget? _buildAnimatedAppBar() { - if (!_showAppBar) return null; - - return PreferredSize( - preferredSize: const Size.fromHeight(kToolbarHeight), - child: SlideTransition( - position: _appBarSlideAnimation, - child: FadeTransition( - opacity: _appBarOpacityAnimation, - child: AppBar( - title: const Text( - 'AppSkel POS Owner', - style: TextStyle( - fontWeight: FontWeight.w700, - fontSize: 18, - letterSpacing: -0.5, - ), - ), - foregroundColor: AppColor.textPrimary, - elevation: 0, - scrolledUnderElevation: 0, - shadowColor: AppColor.primary.withOpacity(0.1), - actions: [ActionIconButton(onTap: () {}, icon: LineIcons.bell)], - ), - ), - ), - ); - } - @override Widget build(BuildContext context) { return Scaffold( backgroundColor: AppColor.background, - appBar: _buildAnimatedAppBar(), body: CustomScrollView( - controller: _scrollController, - physics: const BouncingScrollPhysics(), + physics: const BouncingScrollPhysics(parent: ClampingScrollPhysics()), slivers: [ - // Enhanced Header - SliverToBoxAdapter( - child: AnimatedBuilder( - animation: _headerAnimationController, - builder: (context, child) { - return Transform.translate( - offset: Offset( - 0, - 50 * (1 - _headerAnimationController.value), + // SliverAppBar with HomeHeader as background + SliverAppBar( + expandedHeight: 250, // Adjust based on HomeHeader height + floating: true, + pinned: true, + snap: true, + elevation: 0, + scrolledUnderElevation: 8, + backgroundColor: AppColor.primary, + surfaceTintColor: Colors.transparent, + flexibleSpace: LayoutBuilder( + builder: (BuildContext context, BoxConstraints constraints) { + // Calculate collapse progress (0.0 = expanded, 1.0 = collapsed) + final double expandedHeight = 200; + final double collapsedHeight = + kToolbarHeight + MediaQuery.of(context).padding.top; + final double currentHeight = constraints.maxHeight; + + double collapseProgress = + 1.0 - + ((currentHeight - collapsedHeight) / + (expandedHeight - collapsedHeight)); + collapseProgress = collapseProgress.clamp(0.0, 1.0); + + return FlexibleSpaceBar( + title: Opacity( + opacity: collapseProgress, // Title muncul saat collapse + child: Row( + children: [ + Expanded( + child: Text( + 'AppSkel POS Owner', + style: AppStyle.xl.copyWith( + fontWeight: FontWeight.w700, + fontSize: 18, + letterSpacing: -0.5, + color: AppColor.white, + ), + ), + ), + ActionIconButton(onTap: () {}, icon: LineIcons.bell), + ], + ), ), - child: Opacity( - opacity: _headerAnimationController.value, - child: HomeHeader(), + titlePadding: const EdgeInsets.only(left: 16, bottom: 16), + background: AnimatedBuilder( + animation: _headerAnimationController, + builder: (context, child) { + return Transform.translate( + offset: Offset( + 0, + 50 * (1 - _headerAnimationController.value), + ), + child: Opacity( + opacity: _headerAnimationController.value, + child: HomeHeader(), + ), + ); + }, ), ); },