From 6770e70edd6f3aad786fda552fb729627dbd1198 Mon Sep 17 00:00:00 2001 From: pahmiudahgede Date: Tue, 27 May 2025 10:14:55 +0700 Subject: [PATCH] update: improve splash screen transition to navigation --- lib/core/router.dart | 49 +++- lib/core/utils/exportimportview.dart | 1 + lib/core/utils/navigation.dart | 248 ++++++++++-------- lib/features/launch/screen/splash_screen.dart | 4 +- 4 files changed, 177 insertions(+), 125 deletions(-) diff --git a/lib/core/router.dart b/lib/core/router.dart index 0ca86e9..7be2bd9 100644 --- a/lib/core/router.dart +++ b/lib/core/router.dart @@ -3,17 +3,35 @@ import 'package:rijig_mobile/core/utils/exportimportview.dart'; final router = GoRouter( routes: [ GoRoute(path: '/', builder: (context, state) => SplashScreen()), - GoRoute(path: '/cmapview', builder: (context, state) => CollectorRouteMapScreen()), + GoRoute( + path: '/cmapview', + builder: (context, state) => CollectorRouteMapScreen(), + ), GoRoute( path: '/onboarding', - builder: (context, state) => OnboardingPageScreen(), + pageBuilder: (context, state) { + var key = state.pageKey; + return transisi(OnboardingPageScreen(), key); + }, ), GoRoute(path: '/login', builder: (context, state) => LoginScreen()), GoRoute(path: '/clogin', builder: (context, state) => CloginScreen()), - GoRoute(path: '/welcomec', builder: (context, state) => WelcomeCollectorScreen()), - GoRoute(path: '/verifidentity', builder: (context, state) => UploadKtpScreen()), - GoRoute(path: '/berandapengepul', builder: (context, state) => ChomeCollectorScreen()), - GoRoute(path: '/cpickuphistory', builder: (context, state) => PickupHistoryScreen()), + GoRoute( + path: '/welcomec', + builder: (context, state) => WelcomeCollectorScreen(), + ), + GoRoute( + path: '/verifidentity', + builder: (context, state) => UploadKtpScreen(), + ), + GoRoute( + path: '/berandapengepul', + builder: (context, state) => ChomeCollectorScreen(), + ), + GoRoute( + path: '/cpickuphistory', + builder: (context, state) => PickupHistoryScreen(), + ), // Rute untuk verifikasi OTP dengan ekstraksi data dari path GoRoute( @@ -45,7 +63,10 @@ final router = GoRouter( // Rute untuk halaman-halaman utama GoRoute(path: '/home', builder: (context, state) => HomeScreen()), - GoRoute(path: '/dataperforma', builder: (context, state) => DatavisualizedScreen()), + GoRoute( + path: '/dataperforma', + builder: (context, state) => DatavisualizedScreen(), + ), GoRoute(path: '/activity', builder: (context, state) => ActivityScreen()), GoRoute( path: '/requestpickup', @@ -86,3 +107,17 @@ final router = GoRouter( ), ], ); + +CustomTransitionPage transisi(Widget page, key) { + return CustomTransitionPage( + transitionDuration: const Duration(milliseconds: 1200), + child: page, + key: key, + transitionsBuilder: (key, animation, secondaryAnimation, page) { + return FadeTransition( + opacity: CurveTween(curve: Curves.easeInOut).animate(animation), + child: page, + ); + }, + ); +} diff --git a/lib/core/utils/exportimportview.dart b/lib/core/utils/exportimportview.dart index 40e2b74..5833e4a 100644 --- a/lib/core/utils/exportimportview.dart +++ b/lib/core/utils/exportimportview.dart @@ -1,3 +1,4 @@ +export 'package:flutter/material.dart'; export 'package:go_router/go_router.dart'; export 'package:rijig_mobile/core/utils/navigation.dart'; export 'package:rijig_mobile/features/activity/presentation/screen/activity_screen.dart'; diff --git a/lib/core/utils/navigation.dart b/lib/core/utils/navigation.dart index 0753a41..d60a228 100644 --- a/lib/core/utils/navigation.dart +++ b/lib/core/utils/navigation.dart @@ -16,9 +16,35 @@ class NavigationPage extends StatefulWidget { State createState() => _NavigationPageState(); } -class _NavigationPageState extends State { +class _NavigationPageState extends State + with SingleTickerProviderStateMixin { + late AnimationController _controller; + late Animation _slideAnimation; int _selectedIndex = 0; + @override + void initState() { + super.initState(); + _controller = AnimationController( + duration: const Duration(milliseconds: 2000), + vsync: this, + ); + + _slideAnimation = Tween( + begin: const Offset(1.0, 0), + end: Offset.zero, + ).animate(CurvedAnimation(parent: _controller, curve: Curves.easeOut)); + + _controller.forward(); + _loadSelectedIndex(); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + _loadSelectedIndex() async { SharedPreferences prefs = await SharedPreferences.getInstance(); setState(() { @@ -31,136 +57,126 @@ class _NavigationPageState extends State { prefs.setInt('last_selected_index', index); } - @override - void initState() { - super.initState(); - _loadSelectedIndex(); - } - void _onItemTapped(int index) { if (index == 2) { router.push("/requestpickup"); } else { - setState(() { - _selectedIndex = index; - }); + setState(() => _selectedIndex = index); _saveSelectedIndex(index); } } @override Widget build(BuildContext context) { - return Scaffold( - extendBody: true, - backgroundColor: whiteColor, - body: IndexedStack( - index: _selectedIndex, - children: const [ - HomeScreen(), - ActivityScreen(), - Text(""), - CartScreen(), - ProfilScreen(), - ], - ), - bottomNavigationBar: Theme( - data: Theme.of(context).copyWith( - splashFactory: NoSplash.splashFactory, - highlightColor: Colors.transparent, - ), - child: Visibility( - visible: _selectedIndex != 2, - child: BottomAppBar( - shape: const CircularNotchedRectangle(), - padding: PaddingCustom().paddingHorizontal(2), - elevation: 0, - height: 67, - color: primaryColor, - clipBehavior: Clip.antiAlias, - notchMargin: 3.0, - child: BottomNavigationBar( - type: BottomNavigationBarType.fixed, - backgroundColor: Colors.transparent, + return Container( + color: Theme.of(context).scaffoldBackgroundColor, + child: SlideTransition( + position: _slideAnimation, + child: Scaffold( + extendBody: true, + backgroundColor: whiteColor, + body: IndexedStack( + index: _selectedIndex, + children: const [ + HomeScreen(), + ActivityScreen(), + Text(""), + CartScreen(), + ProfilScreen(), + ], + ), + bottomNavigationBar: Visibility( + visible: _selectedIndex != 2, + child: BottomAppBar( + shape: const CircularNotchedRectangle(), + padding: PaddingCustom().paddingHorizontal(2), elevation: 0, - showSelectedLabels: true, - showUnselectedLabels: true, - selectedItemColor: secondaryColor, - unselectedItemColor: whiteColor, - currentIndex: _selectedIndex, - onTap: _onItemTapped, - items: [ - BottomNavigationBarItem( - icon: Icon(Iconsax.home_2), - activeIcon: Icon(Iconsax.home_2, size: 26), - label: 'Beranda', - ), - BottomNavigationBarItem( - icon: Icon(Iconsax.note_favorite), - activeIcon: Icon(Iconsax.note_favorite, size: 26), - label: 'Aktivitas', - ), - const BottomNavigationBarItem( - icon: SizedBox.shrink(), - label: '', - ), - BottomNavigationBarItem( - icon: Icon(Iconsax.shopping_cart), - activeIcon: Icon(Iconsax.shopping_cart, size: 26), - label: 'Keranjang', - ), - BottomNavigationBarItem( - icon: Icon(Iconsax.user), - activeIcon: Icon(Iconsax.user, size: 26), - label: 'Profil', - ), - ], - selectedLabelStyle: Tulisan.customText( - color: secondaryColor, - fontsize: 14, - fontWeight: FontWeight.w600, - ), - unselectedLabelStyle: Tulisan.customText( - color: whiteColor, - fontsize: 12, - fontWeight: FontWeight.w400, - ), - ), - ), - ), - ), - - floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, - floatingActionButton: Container( - width: 78, - height: 78, - decoration: BoxDecoration( - shape: BoxShape.circle, - gradient: LinearGradient( - colors: [secondaryColor, primaryColor], - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - ), - border: Border.all(color: whiteColor, width: 4), - ), - child: RawMaterialButton( - onPressed: () { - router.push("/requestpickup"); - }, - shape: const CircleBorder(), - elevation: 0, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon(Iconsax.archive_2, color: whiteColor, size: 30), - Text( - "Mulai", - style: Tulisan.customText( - color: whiteColor, + height: 67, + color: primaryColor, + clipBehavior: Clip.antiAlias, + notchMargin: 3.0, + child: BottomNavigationBar( + type: BottomNavigationBarType.fixed, + backgroundColor: Colors.transparent, + elevation: 0, + showSelectedLabels: true, + showUnselectedLabels: true, + selectedItemColor: secondaryColor, + unselectedItemColor: whiteColor, + currentIndex: _selectedIndex, + onTap: _onItemTapped, + items: [ + BottomNavigationBarItem( + icon: Icon(Iconsax.home_2), + activeIcon: Icon(Iconsax.home_2, size: 26), + label: 'Beranda', + ), + BottomNavigationBarItem( + icon: Icon(Iconsax.note_favorite), + activeIcon: Icon(Iconsax.note_favorite, size: 26), + label: 'Aktivitas', + ), + const BottomNavigationBarItem( + icon: SizedBox.shrink(), + label: '', + ), + BottomNavigationBarItem( + icon: Icon(Iconsax.shopping_cart), + activeIcon: Icon(Iconsax.shopping_cart, size: 26), + label: 'Keranjang', + ), + BottomNavigationBarItem( + icon: Icon(Iconsax.user), + activeIcon: Icon(Iconsax.user, size: 26), + label: 'Profil', + ), + ], + selectedLabelStyle: Tulisan.customText( + color: secondaryColor, fontsize: 14, fontWeight: FontWeight.w600, ), + unselectedLabelStyle: Tulisan.customText( + color: whiteColor, + fontsize: 12, + fontWeight: FontWeight.w400, + ), ), - ], + ), + ), + floatingActionButtonLocation: + FloatingActionButtonLocation.centerDocked, + floatingActionButton: Container( + width: 78, + height: 78, + decoration: BoxDecoration( + shape: BoxShape.circle, + gradient: LinearGradient( + colors: [secondaryColor, primaryColor], + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ), + border: Border.all(color: whiteColor, width: 4), + ), + child: RawMaterialButton( + onPressed: () => router.push("/requestpickup"), + shape: const CircleBorder(), + elevation: 0, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Iconsax.archive_2, color: whiteColor, size: 30), + Text( + "Mulai", + style: Tulisan.customText( + color: whiteColor, + fontsize: 14, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), ), ), ), diff --git a/lib/features/launch/screen/splash_screen.dart b/lib/features/launch/screen/splash_screen.dart index 218bded..c43505f 100644 --- a/lib/features/launch/screen/splash_screen.dart +++ b/lib/features/launch/screen/splash_screen.dart @@ -80,8 +80,8 @@ class SplashScreenState extends State { if (_isCheckingConnection) Align( - alignment: Alignment.center, - child: CircularProgressIndicator(), + alignment: Alignment.bottomCenter, + child: CircularProgressIndicator(color: whiteColor,), ), ], ),