maheshj01 / navbar_router

A Navbar widget for advanced usecases to improve user experience and save your time.
https://docs.maheshjamdade.com/navbar_router/
MIT License
28 stars 6 forks source link

Unexpected Blackout Transition Animation in NavBarRouter #35

Closed tushar4303 closed 9 months ago

tushar4303 commented 9 months ago

Describe the bug A clear and concise description of what the bug is.

To Reproduce Steps to reproduce the behavior: Switch between pages

Expected behavior Smooth and subtle transition between routes without any blackout animation.

Screenshots

https://github.com/maheshmnj/navbar_router/assets/88235295/e481a3be-36b0-4c49-97d0-5ae5ad2aaa1a

Desktop (please complete the following information):

Smartphone (please complete the following information):

import 'firebase_options.dart'; import 'utils/globals.dart';

Future backgroundHandler(RemoteMessage message) async { if (message.notification != null) { // Show a notification and handle tap events print("handling a background notification"); } }

// FlutterLocalNotificationsPlugin notificationsPlugin = // FlutterLocalNotificationsPlugin();

void main() async { SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]); WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp( name: "CluedIn", options: DefaultFirebaseOptions.currentPlatform, ); await Hive.initFlutter(); await Hive.openBox('userBox');

bool isLoggedIn = Hive.box('userBox').get('isLoggedIn', defaultValue: false);

FirebaseMessaging.onBackgroundMessage(backgroundHandler); runApp(myApp(isLoggedIn: isLoggedIn)); }

class myApp extends StatelessWidget { final bool isLoggedIn; myApp({ Key? key, required this.isLoggedIn, }) : super(key: key); final GlobalKey navigatorKey = GlobalKey(debugLabel: "Main Navigator"); //

@override Widget build(BuildContext context) { return MaterialApp( navigatorKey: navigatorKey, scaffoldMessengerKey: snackbarKey, themeMode: ThemeMode.light, debugShowCheckedModeBanner: false, theme: MyTheme.lightTheme(context), darkTheme: MyTheme.darkTheme(context), // home: HomePage(), // home: MyPhone(), home: isLoggedIn ? HomePage() : LoginPage() // initialRoute: isLoggedIn ? HomePage() : LoginPage(); ); } }

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

List items = [ NavbarItem( Icons.home, 'Home', ), NavbarItem( Icons.notifications, 'Notifications', ), NavbarItem(Icons.explore, 'Explore'), NavbarItem(Icons.person, 'Profile'), ];

final Map<int, Map<String, Widget>> _routes = { 0: { '/': HomeScreen(), }, 1: { '/': NotificationPage(), }, 2: { '/': MyEvents(), }, 3: { '/': MyProfile(), }, };

DateTime oldTime = DateTime.now(); DateTime newTime = DateTime.now();

@override Widget build(BuildContext context) { return NavbarRouter( errorBuilder: (context) { return const Center(child: Text('Error 404')); }, onBackButtonPressed: (isExitingApp) { if (isExitingApp) { newTime = DateTime.now(); int difference = newTime.difference(oldTime).inMilliseconds; oldTime = newTime; if (difference < 1000) { NavbarNotifier.hideSnackBar(context); return isExitingApp; } else { final state = Scaffold.of(context); NavbarNotifier.showSnackBar( context, "Tap back button again to exit", bottom: state.hasFloatingActionButton ? 0 : kNavbarHeight, ); return false; } } else { return isExitingApp; } }, destinationAnimationCurve: Curves.fastOutSlowIn, destinationAnimationDuration: 600, decoration: NavbarDecoration( backgroundColor: const Color.fromRGBO(251, 251, 252, 1), selectedIconTheme: const IconThemeData(color: Colors.black), navbarType: BottomNavigationBarType.fixed, // elevation: 18, selectedLabelTextStyle: const TextStyle(color: Colors.black), enableFeedback: true), destinations: [ for (int i = 0; i < items.length; i++) DestinationRouter( navbarItem: items[i], destinations: [ for (int j = 0; j < _routes[i]!.keys.length; j++) Destination( route: _routes[i]!.keys.elementAt(j), widget: _routes[i]!.values.elementAt(j), ), ], // initialRoute: _routes[i]!.keys.first, ), ], ); } }

// ignore_for_file: prefer_const_constructors


 **Link to my project repo:**
 https://github.com/tushar4303/CluedIn-Flutter

  **Link to individual four pages:**
https://github.com/tushar4303/CluedIn-Flutter/blob/main/lib/screens/homescreen.dart
https://github.com/tushar4303/CluedIn-Flutter/blob/main/lib/screens/Notifications/notification_page.dart
https://github.com/tushar4303/CluedIn-Flutter/blob/main/lib/screens/Profile/profile.dart
https://github.com/tushar4303/CluedIn-Flutter/blob/main/lib/screens/Events/events.dart
maheshj01 commented 9 months ago

Hi, @tushar4303, Thanks for filing the issue. I think this is the same issue as https://github.com/maheshmnj/navbar_router/issues/6 I need to reinvestigate how fade transition works. Meanwhile please follow up on that issue, I know it has been quite a while since it hasn't been solved. I will try my best to solve it within a week.

Closing as duplicate of the linked issue. Incase you disagree, please feel free to write in the comments and I would be happy to rereview.

tushar4303 commented 9 months ago

Certainly! Here's a reply you can use:

Hi @maheshmnj ,

Thank you for your prompt response and for linking the related issue #6. I'll keep an eye on that to stay updated on the progress.

In the meantime, I'll explore using the AnimatedSwitcher as suggested in the mentioned issue. Additionally, I have a question regarding implementing a feature in v0.3.3. I'm using four main pages as the base route, and subpages inside them are pushed using navigator.pushNamed. I want the back button behavior to navigate back to the home page when pressed on any of the four pages (similar to Instagram), and on a double tap on the home page, I should exit the app.

I tried the code from the documentation, but it didn't work as expected. Could you please provide guidance or share a code snippet for achieving this behavior?

Thanks again for your assistance!

maheshj01 commented 9 months ago

@tushar4303 to pop to base route from a deeply nested route from any tab you just have to pass shouldPopToBaseRoute: true to navbar_router (true by default) so you don't have to explicitly do anything to achieve that behavior.

for handling the double press backbutton to exit you have to implement your custom logic in onBackButtonPressed

onBackButtonPressed: A function which defines whether it is the root Navigator or not. if the method returns true then the Navigator is at the base of the navigator stack

Heres the implementation from the example app

  DateTime oldTime = DateTime.now();
  DateTime newTime = DateTime.now();

 onBackButtonPressed: (isExitingApp) {
          if (isExitingApp) {
            newTime = DateTime.now();
           // time difference between consecutive taps
            int difference = newTime.difference(oldTime).inMilliseconds;
            oldTime = newTime;
            if (difference < 1000) {
              NavbarNotifier.hideSnackBar(context);
              return isExitingApp;
            } else {
              final state = Scaffold.of(context);
              NavbarNotifier.showSnackBar(
                context,
                "Tap back button again to exit",
                bottom: state.hasFloatingActionButton ? 0 : kNavbarHeight,
              );
              return false;
            }
          } else {
            return isExitingApp;
          }
        },

You can see both of those features in action by running the example app. Let me know if any of that doesn't work as intended.