Flutter Invalid argument: Maximum call stack size exceeded - flutter

I am having an exception that I don't understand in my Flutter app.
Here is the code :
main.dart:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Qatar22',
debugShowCheckedModeBanner: false,
theme: new ThemeData(
accentColor: Colors.black,
indicatorColor: Colors.black,
highlightColor: Colors.black,
bottomAppBarColor: Colors.black,
primaryColor: Color(0xFFffffff),
primaryColorDark: Color(0xffffff)),
home: SplashScreen(),
routes: <String, WidgetBuilder>{
SPLASH_SCREEN: (BuildContext context) => SplashScreen(),
FEED_SCREEN: (BuildContext context) => FeedScreen(),
PROGRAM_SCREEN: (BuildContext context) => ProgramScreen(),
},
);
}
}
FeedScreen:
class FeedScreen extends StatefulWidget {
#override
State<FeedScreen> createState() => _FeedScreenState();
}
/// This is the private State class that goes with MyStatefulWidget.
class _FeedScreenState extends State<FeedScreen> {
int _selectedIndex = 0;
final List<Widget> _widgetOptions = [FeedScreen(), ProgramScreen()];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Gallery'),
),
body: Center(
child: _widgetOptions.elementAt(_selectedIndex),
),
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.news_solid),
label: 'Feed',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.sportscourt_fill),
label: 'Program',
)
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.red.shade900,
onTap: (index) {
switch (index) {
case 0:
Navigator.pushNamed(context, FEED_SCREEN);
break;
case 1:
Navigator.pushNamed(context, PROGRAM_SCREEN);
break;
}
}),
);
}
}
and I am getting this exception:
The following JSRangeError was thrown building NotificationListener<LayoutChangedNotification>:
Invalid argument: Maximum call stack size exceeded
The relevant error-causing widget was:
Scaffold file:///home/project/lib/screens/feed/feed-screen.dart:21:12
Would you help me please as I am new to Flutter.

It seems you called FeedScreen inside itself at this line:
final List<Widget> _widgetOptions = [FeedScreen(), ProgramScreen()];
It can be one of the reason that this problem happened.
Please don't use FeedScreen() inside itself and use other classes instead.

You have this error because there is an infinite loop with FeedScreen

You have this error because there is infinite size, you can use SingleChildScrollView.

Related

How to fix BottomNavigationBar disappearance issue in Flutter App

I am facing an issue with my bottom navigation bar. The problem is that the bottom navigation bar disappears whenever I navigate to another page.
I am using the following code to navigate to another page:
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (BuildContext context) => WorkoutsPage()
));
Here is a summarized part of the BottomBar
class BottomBar extends StatefulWidget {
const BottomBar({Key? key}) : super(key: key);
#override
State<BottomBar> createState() => _BottomBarState();
}
class _BottomBarState extends State<BottomBar> {
int _selectedIndex = 0;
static final List<Widget> _widgetOptions = <Widget>[
HomeScreen(),
WorkoutsPage(),
................
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
//print('Tapped index is: ${_selectedIndex}');
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: _widgetOptions[_selectedIndex],
),
bottomNavigationBar: Column(
children: [
BottomNavigationBar(
currentIndex: _selectedIndex,
onTap: _onItemTapped,
..................................
type: BottomNavigationBarType.fixed,
items: const [
BottomNavigationBarItem(
icon: Icon(FluentSystemIcons.ic_fluent_home_regular),
activeIcon: Icon(FluentSystemIcons.ic_fluent_home_filled),
label: "Home"),
BottomNavigationBarItem(
icon:
Icon(FluentSystemIcons.ic_fluent_clipboard_text_regular),
activeIcon:
Icon(FluentSystemIcons.ic_fluent_clipboard_text_filled),
label: "Plan"),
Here is the main.dart
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
routes: {
'/': (context) => _defaultHome,
'/home': (context) => const BottomBar(),
'/login': (context) => const LoginPage(),
'/register': (context) => const RegisterPage(),
},
);
}
My question what should I do to keep the bottombar when I use
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (BuildContext context) => WorkoutsPage()
));
after clicking a submit button or something
BottomBar is a page. When you use pushReplacement, You move to another Scaffold page that is no BottomBar.
An alternative is to turn Column widget of bottomNavigationBar into a separate StatefulWidget and start passing it in all Scaffold pages.
Keep selectedIndex as a global variable so that its value remains even when you change to another route.

Changing the Scaffold's body dynamically

I'm new to flutter and in need of help with this project I'm working on.
I'm trying to change the content of the body property of the Scaffold widget dynamically based on what the user clicked on the bottomNavigationBar.
I am trying to use the Provider state management 'cause I'm trying to learn while I'm creating some apps.
Here's what I got;
main.dart
void main() {
runApp(Pananta());
}
class Pananta extends StatefulWidget {
Pananta({Key? key}) : super(key: key);
#override
State<Pananta> createState() => _PanantaState();
}
class _PanantaState extends State<Pananta> {
int pageIndex = 0;
void changePage() {
setState(() {
Provider.of<ScreenData>(context).pageIndex;
});
}
#override
Widget build(BuildContext context) {
int screenDataIndex = Provider.of<ScreenData>(context).selectedIndex;
return ChangeNotifierProvider<ScreenData>(
create: (_) => ScreenData(),
builder: (context, child) =>
ScreenData.pages[context.watch<ScreenData>().selectedIndex],
child: MaterialApp(
theme: ThemeData(fontFamily: 'Poppins'),
home: SafeArea(
child: Scaffold(
body: screenDataIndex == 0
? ScreenData.pages[0]
: ScreenData.pages[screenDataIndex],
bottomNavigationBar: BottomBarMenu(),
),
),
),
);
}
}
screen_data.dart
class ScreenData extends ChangeNotifier {
int pageIndex = 0;
static List<Widget> pages = [
const HomePage(),
UserProfile(),
];
set selectedpage(int selected) {
pageIndex = selected;
}
int get selectedIndex {
notifyListeners();
return pageIndex;
}
}
The error that I'm getting:
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following ProviderNotFoundException was thrown building Pananta(dirty, state:
_PanantaState#683a3):
Error: Could not find the correct Provider<ScreenData> above this Pananta Widget
This happens because you used a `BuildContext` that does not include the provider
of your choice. There are a few common scenarios:
- You added a new provider in your `main.dart` and performed a hot-reload.
To fix, perform a hot-restart.
- The provider you are trying to read is in a different route.
Providers are "scoped". So if you insert of provider inside a route, then
other routes will not be able to access that provider.
- You used a `BuildContext` that is an ancestor of the provider you are trying to read.
Make sure that Pananta is under your MultiProvider/Provider<ScreenData>.
This usually happens when you are creating a provider and trying to read it immediately.
For example, instead of:
` Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// Will throw a ProviderNotFoundError, because `context` is associated
// to the widget that is the parent of `Provider<Example>`
child: Text(context.watch<Example>().toString()),
);
}`
consider using `builder` like so:
`Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// we use `builder` to obtain a new `BuildContext` that has access to the provider
builder: (context, child) {
// No longer throws
return Text(context.watch<Example>().toString());
}
);
}`
I think the int screenDataIndex = Provider.of<ScreenData>(context).selectedIndex; line is what's causing the issue, because when I remove it and set the body to ScreenData.pages[0] the error goes away -- I can't figure out what to do with it. Any help or articles that I can read will be very much appreciated. Thank you!
I will suggest separating the context to read the provider, and using Consumer widget inside widget tree.
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider<ScreenData>(
create: (_) => ScreenData(),
child: MaterialApp(
theme: ThemeData(fontFamily: 'Poppins'),
home: Pananta(),
),
);
}
}
class Pananta extends StatefulWidget {
Pananta({Key? key}) : super(key: key);
#override
State<Pananta> createState() => _PanantaState();
}
class _PanantaState extends State<Pananta> {
int pageIndex = 0;
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(body: Consumer<ScreenData>(
builder: (context, value, child) {
final currentPage = value.pageIndex;
return currentPage == 0
? ScreenData.pages[0]
: ScreenData.pages as Widget;
},
)),
);
}
}
try a configuration like this:
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return const MaterialApp(
title: _title,
home: MyStatefulWidget(),
);
}
}
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({super.key});
#override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
int _selectedIndex = 0;
static const TextStyle optionStyle =
TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
static const List<Widget> _widgetOptions = <Widget>[
Text(
'Index 0: Home',
style: optionStyle,
),
Text(
'Index 1: Business',
style: optionStyle,
),
Text(
'Index 2: School',
style: optionStyle,
),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('BottomNavigationBar Sample'),
),
body: Center(
child: _widgetOptions.elementAt(_selectedIndex),
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
label: 'Business',
),
BottomNavigationBarItem(
icon: Icon(Icons.school),
label: 'School',
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
),
);
}
}
Create a list of widget and put inside screens you want show.Create relatives BottomNavigationBarItem and the onTap function which update index with selectedIndex.
I think your code is harder than necessary. Try and let me know. Nice coding!

Flutter: assertion: line 4269 pos 14 : 'owner!._debugCurrentBuildTarget == this': is not true

I'm making an "inventory" app, to keep track of objects food etc in my house. I wanted to use a navigator, to make multiple pages, without "modifying" the widgets in the scaffold.
This is my code: (i have as you can see multiple file, ask me if you need something else)
Just to be clear, the utils.dart is an export file that I use to import every thing else
import 'package:flutter/material.dart';
import 'package:storage_system/utils.dart';
import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Storage System',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.yellow,
),
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int _index = 0;
void _onTap(int i) {
setState(() {
_index = i;
});
}
Future<void> getBarcodeData() async {
String resultData = await FlutterBarcodeScanner.scanBarcode(
"0xFFFFFF", "Close", false, ScanMode.BARCODE);
print(resultData);
}
Widget selectPage(int i) {
switch (i) {
case 0:
return MainPage();
case 1:
return SettingsPage();
default:
return Container();
}
}
#override
Widget build(BuildContext context) => Navigator(
onGenerateRoute: (settings) => MaterialPageRoute(
builder: (context) => Container(
child: Scaffold(
floatingActionButtonLocation:
FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
onPressed: getBarcodeData,
child: Icon(Icons.add),
),
appBar: AppBar(
actions: <Widget>[],
title: Text(
"Storage System",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 28),
),
),
bottomNavigationBar: BottomNavigationBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home), label: "Home"),
BottomNavigationBarItem(
icon: Icon(Icons.settings), label: "Setings")
],
currentIndex: _index,
onTap: _onTap,
elevation: 15,
),
body: Container(
child: selectPage(_index),
),
),
)),
);
}

Error: Could not find the correct Provider<Cart> above this Consumer<Cart> Widget

I put provider above material app so I can use it in every widget in-app right?
so why this error
and my code is
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider.value(
value: Cart(),
),
ChangeNotifierProvider.value(value: ProductsProvider()),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.purple,
accentColor: Colors.deepOrange,
fontFamily: 'Lato',
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: ProductOverviewScreen(),
routes: {ProductDetailScreen.routeName: (ctx) => ProductDetailScreen()},
),
);
}
}
and this screen has the error
enum filterOptions { Favorites, All }
class ProductOverviewScreen extends StatefulWidget {
#override
_ProductOverviewScreenState createState() => _ProductOverviewScreenState();
}
class _ProductOverviewScreenState extends State<ProductOverviewScreen> {
var _showOnlyFavorites = false;
#override
Widget build(BuildContext context) {
//final cart = Provider.of<Cart>(context);
return Scaffold(
appBar: AppBar(
title: Text("MyShop"),
actions: [
PopupMenuButton(
onSelected: (selectedValue) {
setState(() {
if (selectedValue == filterOptions.Favorites) {
_showOnlyFavorites = true;
} else if (selectedValue == filterOptions.All) {
_showOnlyFavorites = false;
}
});
},
icon: Icon(Icons.more_vert),
itemBuilder: (_) => [
PopupMenuItem(
child: Text("Only Favorites"),
value: filterOptions.Favorites),
PopupMenuItem(
child: Text("Show All"), value: filterOptions.All),
]),
Consumer<Cart>(
builder: (_, cartData, ch) => Badge(
child: ch,
value: cartData.itemCount.toString(),
),
child: IconButton(
icon: Icon(Icons.shopping_cart),
onPressed: () {},
),
)
],
),
body: ProductsGrid(_showOnlyFavorites));
}
}
the error in the consumer is
Error: Could not find the correct Provider above this Consumer Widget
why does this screen cant know the Cart provider?
any help please ?
I don't have enough reputation to comment, but your sample works fine on my end with flutter 1.22.5 and provider 4.3.2. However, I managed to reproduce your problem when accidentally importing a package named flutter_provider and using its Consumer widget. Couldn't imagine this being your problem though.
By the way, you should avoid using the value constructor to create your ChangeNotifier. Either pass a variable or use the default constructor with the create parameter.

How do I add a bottomNavigationBar on one screen, but not others?

I have 3 screens for my app: an enter screen, login, and the main screen. I want the nav bar only to be on the main screen. Which widget should I return in my HomeScreen() page or what should I have in my main.dart page?
Here is the code for the main.dart:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Doctor Consultation App',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
scaffoldBackgroundColor: Colors.white,
visualDensity: VisualDensity.adaptivePlatformDensity),
home: EnterScreen(),
);
}
}
home_screen.dart:
class MainScreen extends StatefulWidget {
#override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
);
}
}
bottom_nav_bar.dart:
class BottomNavScreen extends StatefulWidget {
#override
_BottomNavScreenState createState() => _BottomNavScreenState();
}
class _BottomNavScreenState extends State<BottomNavScreen> {
final List _screens = [
MainScreen(),
Scaffold(),
Scaffold(),
Scaffold(),
];
int _currentIndex = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
body: _screens[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: (index) => setState(() => _currentIndex = index),
type: BottomNavigationBarType.fixed,
backgroundColor: Colors.white,
showSelectedLabels: false,
showUnselectedLabels: false,
selectedItemColor: Palette.primaryRed,
unselectedItemColor: Colors.grey,
elevation: 0.0,
items: [
Icons.home,
Icons.chat_bubble,
Icons.calendar_today,
Icons.person
]
.asMap()
.map((key, value) => MapEntry(
key,
BottomNavigationBarItem(
title: Text(''),
icon: Container(
padding: const EdgeInsets.symmetric(
vertical: 6.0, horizontal: 16.0),
decoration: BoxDecoration(
color: _currentIndex == key
? Palette.primaryRed
: Colors.transparent,
borderRadius: BorderRadius.circular(20.0)),
child: Icon(value)))))
.values
.toList()),
);
}
}
I have already tried doing bottomNavigationBar: BottomNavScreen(), on the home_screen.dart, but I get a ton of errors from the MaterialApp widget.
Change the build of the ButtomNavScreen to this:
#override
Widget build(BuildContext context) {
return BottomNavigationBar(
currentIndex: _currentIndex,
...
And change the build of the MainScreen to something like this:
#override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: BottomNavScreen(),
body: SafeArea(
child: Center(
child: Container(
width: 200,
height: 100,
color: Colors.redAccent,
child: Center(child: Text("sample text")),
),
)
),
);
}