Closed FilyMSakine closed 6 months ago
I almost forget, I'm using go router
for routes and navigation stuff
Full log
══╡ EXCEPTION CAUGHT BY FOUNDATION LIBRARY ╞════════════════════════════════════════════════════════
The following assertion was thrown while dispatching notifications for NotchBottomBarController:
AnimationController.stop() called after AnimationController.dispose()
AnimationController methods should not be used after calling dispose.
'package:flutter/src/animation/animation_controller.dart':
Failed assertion: line 772 pos 7: '_ticker != null'
Either the assertion indicates an error in the framework itself, or we should provide substantially
more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
https://github.com/flutter/flutter/issues/new?template=2_bug.yml
When the exception was thrown, this was the stack:
#2 AnimationController.stop (package:flutter/src/animation/animation_controller.dart:772:7)
#3 AnimationController.value= (package:flutter/src/animation/animation_controller.dart:361:5)
#4 AnimationController.reset (package:flutter/src/animation/animation_controller.dart:382:5)
#5 _AnimatedNotchBottomBarState.initState.<anonymous closure> (package:animated_notch_bottom_bar/src/notch_bottom_bar.dart:106:28)
#6 ChangeNotifier.notifyListeners (package:flutter/src/foundation/change_notifier.dart:403:24)
#7 NotchBottomBarController.jumpTo (package:animated_notch_bottom_bar/src/notch_bottom_bar_controller.dart:12:5)
#8 _AnimatedNotchBottomBarState.build.<anonymous closure>.<anonymous closure> (package:animated_notch_bottom_bar/src/notch_bottom_bar.dart:218:38)
#9 BottomBarInActiveItem.build.<anonymous closure> (package:animated_notch_bottom_bar/src/bottom_bar_inactive_item.dart:35:25)
#10 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:275:24)
#11 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:654:11)
#12 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:311:5)
#13 BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:244:7)
#14 PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:630:9)
#15 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:98:12)
#16 PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:143:9)
#17 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:625:13)
#18 PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:141:18)
#19 PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:127:7)
#20 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:488:19)
#21 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:468:22)
#22 RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:333:11)
#23 GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:413:7)
#24 GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:376:5)
#25 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:323:7)
#26 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:292:9)
#27 _invoke1 (dart:ui/hooks.dart:186:13)
#28 PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:424:7)
#29 _dispatchPointerDataPacket (dart:ui/hooks.dart:119:31)
(elided 2 frames from class _AssertionError)
The NotchBottomBarController sending notification was:
Instance of 'NotchBottomBarController'
═══════════════════════════════════════════════════════════════════════════════════════════════════
import 'dart:developer';
import 'package:animated_notch_bottom_bar/animated_notch_bottom_bar/animated_notch_bottom_bar.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:go_router/go_router.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
MyApp({Key? key}) : super(key: key);
final GoRouter _router = GoRouter(
routes: <RouteBase>[
GoRoute(
path: '/',
builder: (BuildContext context, GoRouterState state) {
return const MyHomePage();
},
),
],
);
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerConfig: _router,
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
/// Controller to handle PageView and also handles initial page
final List<Widget> _items = const <Widget>[
Page2(),
Page3(),
Page1(),
];
late PageController _pageController;
late NotchBottomBarController _notchBottomBarController;
@override
void initState() {
_pageController = PageController();
_notchBottomBarController = NotchBottomBarController();
super.initState();
}
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: PageView(
scrollDirection: Axis.vertical,
controller: _pageController,
physics: const NeverScrollableScrollPhysics(),
children: List<Widget>.generate(
_items.length,
(int index) => Container(
margin: const EdgeInsets.only(),
child: _items[index],
),
),
),
extendBody: true,
bottomNavigationBar: AnimatedNotchBottomBar(
durationInMilliSeconds: 400,
notchBottomBarController: _notchBottomBarController,
showLabel: false,
bottomBarItems: <BottomBarItem>[
const BottomBarItem(
inActiveItem: Icon(
Icons.home_filled,
color: Colors.blueGrey,
),
activeItem: Icon(
Icons.home_filled,
color: Colors.blueAccent,
),
itemLabel: 'Page 1',
),
const BottomBarItem(
inActiveItem: Icon(
Icons.star,
color: Colors.blueGrey,
),
activeItem: Icon(
Icons.star,
color: Colors.blueAccent,
),
itemLabel: 'Page 2',
),
///svg example
BottomBarItem(
inActiveItem: SvgPicture.asset(
'assets/search_icon.svg',
color: Colors.blueGrey,
),
activeItem: SvgPicture.asset(
'assets/search_icon.svg',
color: Colors.white,
),
itemLabel: 'Page 3',
),
],
onTap: (index) {
/// perform action on tab change and to update pages you can update pages without pages
log('current selected index $index');
_pageController.jumpToPage(index);
},
),
);
Future<void> _changeBottomBarItem(int index) async {
_pageController.animateToPage(index, duration: const Duration(milliseconds: 400), curve: Curves.easeInOut);
}
}
}
class Page1 extends StatelessWidget {
const Page1({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(color: Colors.yellow, child: const Center(child: Text('Page 1')));
}
}
class Page2 extends StatelessWidget {
const Page2({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(color: Colors.green, child: const Center(child: Text('Page 2')));
}
}
class Page3 extends StatelessWidget {
const Page3({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(color: Colors.red, child: const Center(child: Text('Page 3')));
}
}
// class Page4 extends StatelessWidget {
// const Page4({Key? key}) : super(key: key);
//
// @override
// Widget build(BuildContext context) {
// return Container(color: Colors.blue, child: const Center(child: Text('Page 4')));
// }
// }
//
// class Page5 extends StatelessWidget {
// const Page5({Key? key}) : super(key: key);
//
// @override
// Widget build(BuildContext context) {
// return Container(color: Colors.lightGreenAccent, child: const Center(child: Text('Page 5')));
// }
// }
@FilyMSakine using your code i create demo and its work fine you can try above code and if found any issue please give me more details so i can regenerate that issues and find solutions for you
@mi-raj04 alright
// my custom go_router
import ...
class CustomGoRouter {
static bool redirected = false;
static GoRouter configuration() => GoRouter(
routes: <RouteBase>[...],
redirect: (context, state) {
if (getIt<SharedPreferencesClient>()
.restoreUserAuthenticationFields() !=
null &&
!redirected) {
redirected = true;
return RouterPath.rootLocation;
}
return state.fullPath;
},
);
static void go(BuildContext context, String routerPath) {
GoRouter.of(context).go(routerPath);
}
static Future<void> push(BuildContext context, String routerPath) async {
GoRouter.of(context).push(routerPath);
}
static void pop(BuildContext context) {
GoRouter.of(context).pop();
}
}
My material page definition
import ...
class App extends StatefulWidget {
const App({super.key});
@override
State<StatefulWidget> createState() => _AppState();
}
class _AppState extends State<App> {
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Sizer(
builder: (BuildContext context, Orientation orientation,
DeviceType deviceType) =>
MaterialApp.router(
routerConfig: CustomGoRouter.configuration(),
theme: ThemeData(...),
localizationsDelegates: const <LocalizationsDelegate<dynamic>>[...],
supportedLocales: const <Locale>[...],
debugShowCheckedModeBanner: false,
),
);
}
}
@mi-raj04 I have the same pageview definition and I'm using jumpToPage(index)
method on onTap
event
Also I have updated my flutter SDK and the package but I'm still getting the same issue
Flutter log
Flutter 3.16.7 • channel stable • https://github.com/flutter/flutter.git
Framework • revision ef1af02aea (12 days ago) • 2024-01-11 15:19:26 -0600
Engine • revision 4a585b7929
Tools • Dart 3.2.4 • DevTools 2.28.5
Packager animated_notch_bottom_bar: ^1.0.1
@FilyMSakine Thank you for expressing your confidence in our team. Unfortunately, after thorough investigation, we were unable to reproduce the issue you mentioned. We explored various approaches to address the issue but encountered no success. Your assistance in providing further details regarding the issue would be greatly appreciated. Additionally, we welcome any contributions or insights you may have to improve our package.
****== Exception caught by foundation library ==================================================== The following assertion was thrown while dispatching notifications for NotchBottomBarController: AnimationController.stop() called after AnimationController.dispose() AnimationController methods should not be used after calling dispose. 'package:flutter/src/animation/animation_controller.dart': Failed assertion: line 795 pos 7: '_ticker != null'
Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause. In either case, please report this assertion by filing a bug on GitHub: https://github.com/flutter/flutter/issues/new?template=2_bug.yml
When the exception was thrown, this was the stack:
======== Exception caught by foundation library ==================================================== The following assertion was thrown while dispatching notifications for NotchBottomBarController: AnimationController.stop() called after AnimationController.dispose() AnimationController methods should not be used after calling dispose. 'package:flutter/src/animation/animation_controller.dart': Failed assertion: line 795 pos 7: '_ticker != null'
Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause. In either case, please report this assertion by filing a bug on GitHub: https://github.com/flutter/flutter/issues/new?template=2_bug.yml
When the exception was thrown, this was the stack:
How to fix my issue
I have three tab VesselDetail,chatScreen and TicketScreen when i switch one tab to another i got above issue and page screen will completely blank how to fix that issue
My code logic is import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import '../../../customWidgets/custom_loader.dart'; import '../../../provider/auth_provider.dart'; import '../../../provider/data_provider.dart'; import '../../../routes_networking/app_routes.dart'; import '../../../routes_networking/router.dart'; import '../../../util/app.dart'; import '../../../util/app_constants.dart'; import 'package:provider/provider.dart'; import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:web_socket_channel/io.dart'; import 'package:web_socket_channel/web_socket_channel.dart'; import '../../../data/model/response/base/notification_model.dart' as nm; import '../../../util/localimages.dart'; import '../authentication/login/login.dart'; import '../chat/chats_screen.dart'; import '../clients/screens/vessels.dart'; import '../ticket/ticket.dart'; import 'package:audioplayers/audioplayers.dart'; import 'package:animated_notch_bottom_bar/animated_notch_bottom_bar/animated_notch_bottom_bar.dart';
class Dashboard extends StatefulWidget { Dashboard({Key? key, NotchBottomBarController? controller}) : super(key: key);
@override
State
class _DashboardState extends State
// const VesselDetails(),
];
// final _pageController = PageController(initialPage: 0); // late final NotchBottomBarController _controller = NotchBottomBarController(index: 0);
// int _selectedIndex = 0; late AnimationController _animationController;
late PageController _pageController; late NotchBottomBarController _controller; bool _isDisposed = false; bool _isControllerDisposed = false;
int maxCount = 3; bool showVesselTab = true; // Set this variable based on your condition // String _screenName = AppConstants.TICKET.toUpperCase(); String? _screenName;
// _onTabTapped(int index) async { // if (!mounted) return; // setState(() { // _currentIndex = index; // switch (_currentIndex) { // case 0: // _screenName = AppConstants.VESSEL.toUpperCase(); // break; // case 1: // _screenName = AppConstants.CHATS.toUpperCase(); // break; // case 2: // _screenName = AppConstants.TICKET.toUpperCase(); // // break; // default: // _screenName = "DASHBOARD"; // } // }); // if (mounted) { // await _pageController.animateToPage(index, // duration: Duration(milliseconds: 300), // curve: Curves.easeInOut // ); // if (!_isControllerDisposed && _controller != null) { // _controller.jumpTo(index); // Ensure NotchBottomBarController is updated // } // } // }
void _onTabTapped(int index) { if (!mounted) return;
setState(() {
_currentIndex = index;
if (!_isDisposed) {
_pageController.jumpToPage(index); // or animateToPage if you want smooth animation
if (!_isControllerDisposed) {
_controller.jumpTo(index); // Ensure NotchBottomBarController is updated
}
}
});
}
bool isCollapse = false; int _previousNotificationCount = 0; // Track previous notification count int _notificationCount = 0; // Track the total number of notifications
int _counter = 0; TextEditingController _dashboardSearch = TextEditingController();
// String _string = "VESSELS"; String userType = '';
// WebSocketChannel? _channel;
@override void initState() { // TODO: implement initState super.initState(); changeuserType(); _updateScreens();
_pageController = PageController(initialPage:_currentIndex);
_controller = NotchBottomBarController(index: _currentIndex);
_animationController = AnimationController(vsync: this);
// Post-frame callback to ensure the widget tree is built before using context
// Check if the user is logged in
if (Provider.of<AuthProvider>(context, listen: false).isLoggedIn()) {
_loadData(context, true); // Load data when the user is logged in
} else {
// Navigate to login screen if not logged in
Navigator.pushNamed(context, MyRouter.getLoginRoute());
}
_initWebSocketNotification();
}
@override void dispose() { print('Disposing controller');
_isDisposed = true;
_isControllerDisposed = true;
print('Rock $_isControllerDisposed');
_pageController.dispose();
_controller?.dispose();
_animationController.dispose();
super.dispose();
}
void _jumpToIndex(int index) { if (!_isDisposed) { _controller.jumpTo(index); } }
@override void didChangeAppLifecycleState(AppLifecycleState state) { if (state == AppLifecycleState.paused) { if (!_isDisposed) { _animationController.stop(); } } }
List
_initWebSocketNotification() { late final WebSocketChannel channel = IOWebSocketChannel.connect('${AppRoutes.WS_NOTIFICATION}'); channel.stream.listen((data) async { try { String messageJson = data; nm.NotificationModel notificationModel = nm.notificationModelFromJson(messageJson);
if (mounted) {
setState(() {
notifications = notificationModel.data.results;
});
}
// Calculate the difference between the current and previous notification counts
int newNotifications = notifications.length - _previousNotificationCount;
if (newNotifications > 0) {
_notificationCount += newNotifications; // Increment the notification count
// Play audio notification
try {
await AudioPlayer().play(AssetSource("mp3/notification.mp3"));
} catch (e) {
print("Error playing audio: $e");
}
}
// Update previous notification count to current count
_previousNotificationCount = notifications.length;
} catch (e) {
print('Error processing WebSocket data: $e, Data: $data');
}
});
}
_initWebSocketNotifications() { late final WebSocketChannel channel = IOWebSocketChannel.connect('${AppRoutes.WS_NOTIFICATION}'); channel?.stream.listen((data) async { try { String messageJson = data; nm.NotificationModel notificationModel = nm.notificationModelFromJson(messageJson);
// // Filter out notifications from the logged-in user
// List<nm.Result> filteredNotifications = notificationModel.data.results
// .where((notification) => notification.userId != loggedInUserID)
// .toList();
//
// setState(() {
// notifications = filteredNotifications;
// });
if (mounted) {
setState(() {
notifications = notificationModel.data.results;
});
}
// Check if the new notification count is greater than the previous count
if (notifications.length > _previousNotificationCount) {
// Play audio notification
try {
await AudioPlayer().play(AssetSource("mp3/notification.mp3"));
} catch (e) {
print("Error playing audio: $e");
}
}
// Update previous notification count
_previousNotificationCount = notifications.length;
} catch (e) {
print('Error processing WebSocket data: $e, Data: $data');
}
});
}
void changeuserType() {
final type = Provider.of
void _updateScreens() {
List
if (userType == '1' || userType == '2') {
newScreens = [
const VesselDetails(),
const ChatScreen(),
const TicketsScreen(),
];
_screenName = AppConstants.VESSEL.toUpperCase();
} else {
newScreens = [
const TicketsScreen(),
const ChatScreen(),
];
_screenName = AppConstants.TICKET.toUpperCase();
}
// Update screens and set PageController's initial page
if (mounted) {
setState(() {
_screens
..clear()
..addAll(newScreens);
_pageController = PageController(initialPage: 0);
});
}
}
// void _updateScreens() { // if (userType == '1' || userType == '2') { // _screens.clear(); // _screens.addAll([ // const VesselDetails(), // const ChatScreen(), // const TicketsScreen(), // ]); // _pageController = PageController(initialPage: _currentIndex); // _screenName = AppConstants.VESSEL.toUpperCase(); // } else { // _screens.clear(); // _screens.addAll([ // const TicketsScreen(), // const ChatScreen(), // ]); // _pageController = PageController(initialPage: _currentIndex); // _screenName = AppConstants.TICKET.toUpperCase(); // } // }
Future
@override Widget build(BuildContext context) {
DataProvider dataProvider = Provider.of<DataProvider>(context);
changeuserType();
_updateScreens();
bool isLoading = dataProvider.isLoading;
var size = MediaQuery.of(context).size;
double appBarHeight = 30;
return isLoading
? CustomLoader()
: SafeArea(
child: Scaffold(
resizeToAvoidBottomInset: false,
appBar: PreferredSize(
preferredSize:
Size(size.width, 100.0), // Adjust preferredSize as needed
child: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [
AppConfigs.PrimaryColor,
AppConfigs.SixthColor,
],
),
),
child: Padding(
padding: EdgeInsets.all(0), // Adjust padding as needed
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// Logout button
SizedBox(
height: appBarHeight,
child: InkWell(
onTap: () {
Provider.of<AuthProvider>(context,
listen: false)
.clearSharedData();
Navigator.pushNamedAndRemoveUntil(
context,
MyRouter.login,
(route) => false,
arguments: const LoginScreen(),
);
},
child: const Align(
alignment: Alignment.center,
child: Icon(
Icons.power_settings_new,
size: 20,
color: AppConfigs.FifthColor,
),
),
),
),
SizedBox(width: size.width / 100),
// Notification bell
// SizedBox(
// height: appBarHeight,
// child: InkWell(
// onTap: (_notificationCount ?? 0) > 0 ? () {
// Navigator.pushNamed(context, MyRouter.notification);
// }: null,
// child: Stack(
// children: [
// const Positioned(
// child: Align(
// alignment: Alignment.center,
// child: Icon(
// Icons.notifications,
// size: 20,
// color: AppConfigs.FifthColor,
// ),
// ),
// ),
// if ((_notificationCount ?? 0) > 0)
// Positioned.fill(
// child: Align(
// alignment: Alignment.topRight,
// child:
// Container(
// width: 15,
// height: 15,
// decoration: BoxDecoration(
// shape: BoxShape.circle,
// color: (_notificationCount ?? 0) > 0?const Color(0xffc32c37): Colors.red,
// border: Border.all(
// color: Colors.white,
// width: 1),
// ),
// child: Center(
// child: Text(
// '${(_notificationCount ?? 0) > 30 ? '30+' : _notificationCount}',
//
// // notifications.length
// // .toString(),
// style: const TextStyle(
// fontSize: 10,
// color: Colors.white),
// ),
// ),
// )
// // : const SizedBox(),
// ),
// ),
// ],
// ),
// ),
// ),
SizedBox(
height: appBarHeight,
child: InkWell(
onTap: notifications != null && notifications.isNotEmpty ? () {
Navigator.pushNamed(context, MyRouter.notification);
}: null,
child: Stack(
children: [
const Positioned(
child: Align(
alignment: Alignment.center,
child: Icon(
Icons.notifications,
size: 20,
color: AppConfigs.FifthColor,
),
),
),
Positioned.fill(
child: Align(
alignment: Alignment.topRight,
child: Container(
width: 15,
height: 15,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: const Color(0xffc32c37),
border: Border.all(color: Colors.white, width: 1),
),
child: Padding(
padding: const EdgeInsets.all(0.0),
child: Center(
child: Text(
notifications != null && notifications.isNotEmpty
? (notifications.length > 50 ? '50+' : notifications.length.toString())
: '0', // Show zero if there are no notifications
style: const TextStyle(fontSize: 10, color: Colors.white),
),
),
),
),
),
),
],
),
),
),
SizedBox(width: size.width / 100),
// Profile Name & Avatar
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
InkWell(
onTap: () {
isDesktop(context)
? Navigator.pushNamedAndRemoveUntil(
context,
MyRouter.profile,
(route) => false)
: Navigator.pushNamed(
context,
MyRouter.profile,
arguments: notifications.length
.toString(),
);
},
child: CircleAvatar(
backgroundColor: AppConfigs.TertiaryColor,
backgroundImage: Provider.of<
DataProvider>(context)
.profileModel
?.profilePic
.isNotEmpty ==
true
? NetworkImage(
Provider.of<DataProvider>(context)
.profileModel!
.profilePic)
: AssetImage(LocalImages.profile_logo)
as ImageProvider<Object>?,
radius: 10,
),
),
SizedBox(width: isDesktop(context) ? 10 : 5),
Visibility(
visible: isDesktop(context),
child: Row(
children: [
InkWell(
onTap: () {
isDesktop(context)
? Navigator
.pushNamedAndRemoveUntil(
context,
MyRouter.profile,
(route) => false)
: Navigator.pushNamed(
context,
MyRouter.profile,
arguments: notifications
.length
.toString(),
);
},
child: Text(
dataProvider.profileModel?.name ??
"",
style: const TextStyle(
color: Colors.white),
),
),
const SizedBox(width: 5),
const Icon(Icons.arrow_drop_down,
color: Colors.white),
],
),
),
],
),
],
),
),
const SizedBox(width: 5),
],
),
),
),
),
body: PageView(
controller: _pageController,
physics: const NeverScrollableScrollPhysics(),
reverse: true,
scrollDirection: Axis.horizontal,
// children: List.generate(_screens.length, (index) => _screens[index]),
children: _screens,
onPageChanged: (index) {
if (!_isControllerDisposed) {
// _controller.jumpTo(index);
setState(() {
_currentIndex = index;
});
print('object $index');
}
},
),
extendBody: true,
bottomNavigationBar: (_screens.length <= maxCount)
? AnimatedNotchBottomBar(
notchBottomBarController: _controller,
color: AppConfigs.TertiaryColor,
itemLabelStyle: const TextStyle(
color: AppConfigs.FifthColor,
fontSize: AppConfigs.TIMELINE_TEXT,
fontFamily: AppConfigs.font,
),
showLabel: true,
shadowElevation: 0,
kBottomRadius: 0,
notchShader: const SweepGradient(
startAngle: 0,
endAngle: 2/ 2,
colors: [
AppConfigs.PrimaryColor,
AppConfigs.SixthColor
],
tileMode: TileMode.mirror,
).createShader(
Rect.fromCircle(center: Offset.zero, radius: 8.0),
),
notchColor: AppConfigs.TertiaryColor,
removeMargins: true,
bottomBarWidth: size.width,
showBlurBottomBar: false,
durationInMilliSeconds: 300,
bottomBarItems: [
BottomBarItem(
inActiveItem: Padding(
padding: const EdgeInsets.only(right: 5),
child:
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(
(userType == '1' || userType == '2')
? Icons.directions_boat_filled_sharp
: Icons.add_card_rounded,
color: Colors.white,
// size: AppConfigs.ICON_SMALL_SIZE,
),
],
),
),
activeItem: Padding(
padding: const EdgeInsets.only(right: 5),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(
(userType == '1' || userType == '2')
? Icons.directions_boat_filled_sharp
: Icons.add_card_rounded,
color: Colors.white,
// size: AppConfigs.ICON_SMALL_SIZE,
),
],
),
),
itemLabel: (userType == '1' || userType == '2')
? AppConstants.VESSEL.toUpperCase()
: AppConstants.TICKET.toUpperCase(),
),
BottomBarItem(
inActiveItem: const Padding(
padding: EdgeInsets.only(right:5),
child: Center(
child: Icon(
Icons.chat,
color: Colors.white,
// size: AppConfigs.ICON_SMALL_SIZE,
),
),
),
activeItem:const Padding(
padding: EdgeInsets.only(right: 5),
child: Center(
child: Icon(
Icons.chat,
color: Colors.white,
// size: AppConfigs.ICON_SMALL_SIZE,
),
),
),
itemLabel: AppConstants.CHATS.toUpperCase(),
),
if (userType == '1' || userType == '2')
BottomBarItem(
inActiveItem:const Padding(
padding: EdgeInsets.only(right: 5),
child: Icon(
Icons.add_card_rounded,
color: Colors.white,
size: 24,
),
),
activeItem:const Padding(
padding: EdgeInsets.only(right: 5),
child: Icon(
Icons.add_card_rounded,
color: Colors.white,
size: 24,
),
),
itemLabel: AppConstants.TICKET.toUpperCase(),
),
],
onTap: (index) {
if (!_isControllerDisposed) {
// Ensure the index is valid
if (index >= 0 && index < _screens.length) {
// Use animateToPage for smooth transitions
_pageController.jumpToPage(index);
// Update the bottom navigation bar's selected index
setState(() {
_currentIndex = index;
if (mounted && _controller != null && !_isControllerDisposed) {
_controller.jumpTo(index);
}
});
// Conditionally call _onTabTapped based on userType
bool shouldHandleTab =
userType != '1' && userType != '2';
if (shouldHandleTab) {
_onTabTapped(index);
}
}
}
},
kIconSize: 30,
)
: null,
),
);
} }
I'm getting this error whenever I try to change items
My code logic is:
Code
Flutter details
I have done so much research about this problem but was unable to find any clue thats why I came here to open a new issue