android – How can I use SlideTransition(or the other animation) in ShellRoute at Flutter?


I’m using ShellRoute in go_router 13.0.0 and BottomNavigationBar to implements Nested Route.
However, I noticed that the transition animation is unnatural when the screen is routed.
So I tried to change routing animation in ShellRoute, but I can’t.
I was also able to find someone who was experiencing similar problems to me.

github issue

And this is my code.

routes.dart

import 'package:baro_project/screens/calendar_screen.dart';
import 'package:baro_project/screens/info_screen.dart';
import 'package:baro_project/screens/youtube_screen.dart';
import 'package:baro_project/widgets/nav_bar.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'screens/login_screen.dart';
import 'screens/main_screen.dart';
import 'screens/noti_screen.dart';

final GlobalKey<NavigatorState> _rootNavigatorKey = GlobalKey<NavigatorState>(debugLabel: 'Root');
final GlobalKey<NavigatorState> _shellNavigatorKey = GlobalKey<NavigatorState>(debugLabel: 'Shell');

final router = GoRouter(navigatorKey: _rootNavigatorKey, initialLocation: '/login', routes: <RouteBase>[
  GoRoute(
    path: '/login',
    builder: (context, state) => const Login(),
  ),
  GoRoute(
    path: '/notification',
    builder: (context, state) => const NotificationManager(),
  ),
  ShellRoute(
    navigatorKey: _shellNavigatorKey,
    builder: (context, state, child) => NavBarWidget(child: child),
    routes: <RouteBase>[
      GoRoute(
        path: '/main',
        builder: (context, state) => const MainScreen(),
      ),
      GoRoute(
        path: '/calendar',
        builder: (context, state) => const CalendarScreen(),
      ),
      GoRoute(
        path: '/youtube',
        builder: (context, state) => const YoutubeScreen(),
      ),
      GoRoute(
        path: '/information',
        builder: (context, state) => const InformationScreen(),
      ),
    ],
  ),
]);

nav_bar.dart

import 'package:baro_project/widgets/app_bar.dart';
import 'package:baro_project/widgets/custom_drawer.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:go_router/go_router.dart';

class NavBarWidget extends StatelessWidget {
  const NavBarWidget({super.key, required this.child});
  final Widget child;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: customAppBar(context),
      body: child,
      bottomNavigationBar: BottomNavigationBar(
        unselectedItemColor: Colors.grey,
        selectedItemColor: Colors.black,
        type: BottomNavigationBarType.fixed,
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: FaIcon(FontAwesomeIcons.house, size: 15.0),
            label: 'Main',
          ),
          BottomNavigationBarItem(
            icon: FaIcon(FontAwesomeIcons.calendar, size: 15.0),
            label: 'Calendar',
          ),
          BottomNavigationBarItem(
            icon: FaIcon(FontAwesomeIcons.youtube, size: 15.0),
            label: 'Youtube',
          ),
          BottomNavigationBarItem(
            icon: FaIcon(FontAwesomeIcons.user, size: 15.0),
            label: 'Information',
          ),
        ],
        onTap: (index) => _onItemTapped(index, context),
        currentIndex: _calculateIndex(context),
      ),
      endDrawer: customDrawer(context),
    );
  }

  void _onItemTapped(int index, BuildContext context) {
    switch (index) {
      case 0:
        GoRouter.of(context).go('/main');
        break;
      case 1:
        GoRouter.of(context).go('/calendar');
        break;
      case 2:
        GoRouter.of(context).go('/youtube');
        break;
      case 3:
        GoRouter.of(context).go('/information');
        break;
    }
  }

  int _calculateIndex(BuildContext context) {
    final currentLocation = GoRouterState.of(context).uri.toString();
    if (currentLocation == '/main') {
      return 0;
    }
    if (currentLocation == '/calendar') {
      return 1;
    }
    if (currentLocation == '/youtube') {
      return 2;
    }
    if (currentLocation == '/information') {
      return 3;
    }
    return 0;
  }
}

I tried this way.

ShellRoute(
    navigatorKey: _shellNavigatorKey,
    builder: (context, state, child)  {
      var animation = ModalRoute.of(context)?.animation;
      if(animation == null) {
        return NavBarWidget(child: child);
      }
      return SlideTransition(
        position: Tween<Offset>(
          begin: const Offset(0, 1),
          end: Offset.zero,
        ).animate(animation),
        child: NavBarWidget(child: child),
      );
    },

In BottomNavigationBar, I wanted the animation moving to the right to be displayed when I clicked on the current item, and the animation moving to the left when I clicked on the left item.

No errors occurred in the code, but the animation did not change.

my application

In addition, the basic routing animation of iOS emulators and Android emulators was being represented differently.
I’m using is an Android emulator.

What should I do?

Latest articles

spot_imgspot_img

Related articles

Leave a reply

Please enter your comment!
Please enter your name here

spot_imgspot_img