Flutter :setState() or markNeedsBuild() called during build
you are doing something before build is complete. we have to wait for the completion of build before doing something…
.without code snippet cant pin point .so How can I do something once a build is complete. you can use
addPostFrameCallback method
This callback is run during a frame, just after the persistent frame callbacks (which is when the main rendering pipeline has been flushed). If a frame is in progress and post-frame callbacks haven't been executed yet, then the registered callback is still executed during the frame. Otherwise, the registered callback is executed during the next frame.
The callbacks are executed in the order in which they have been added.
Post-frame callbacks cannot be unregistered. They are called exactly once.
to your initState modify as follows
WidgetsBinding.instance.addPostFrameCallback((_){
if (type == 'representative') {
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => RepresentativeUi()));
} else if (type == 'student') {
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => StudentUi()));
}
});
You can check out this blog by diddier
Nada Khaled
Updated on December 24, 2022Comments
-
Nada Khaled over 1 year
iam new to flutter and i have tried every solution for this ! and i dont know what to do more than that ! iam trying to get a shared preferences string but when i do that the app crashes and i dont know why ! Iam thinking it could be because of the curved navigation bar , did i do anything wrong ? it keeps showing this error :
The following assertion was thrown building Builder: setState() or markNeedsBuild() called during build. This Overlay widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase. The widget on which setState() or markNeedsBuild() was called was: Overlay-[LabeledGlobalKey<OverlayState>#19d5d] state: OverlayState#13f72(entries: [OverlayEntry#3b74c(opaque: true; maintainState: false), OverlayEntry#91b13(opaque: false; maintainState: true), OverlayEntry#b0313(opaque: false; maintainState: false), OverlayEntry#03775(opaque: false; maintainState: true), OverlayEntry#304cd(opaque: false; maintainState: false), OverlayEntry#7aa01(opaque: false; maintainState: true)]) The widget which was currently being built when the offending call was made was: Builder The relevant error-causing widget was: MaterialApp file:///C:/Users/MuneF/Desktop/mscmu/lib/main.dart:30:10 When the exception was thrown, this was the stack: #0 Element.markNeedsBuild.<anonymous closure> (package:flutter/src/widgets/framework.dart:4167:11) #1 Element.markNeedsBuild (package:flutter/src/widgets/framework.dart:4182:6) #2 State.setState (package:flutter/src/widgets/framework.dart:1253:14) #3 OverlayState.rearrange (package:flutter/src/widgets/overlay.dart:415:5) #4 NavigatorState._flushHistoryUpdates (package:flutter/src/widgets/navigator.dart:3069:16) ...
and i dont know why is this happening . my full code is this : main.dart :
import 'package:curved_navigation_bar/curved_navigation_bar.dart'; import 'package:flutter/material.dart'; import 'package:custom_splash/custom_splash.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'info_card.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'dart:async'; import 'dart:core'; import 'package:http/http.dart' as http; import 'dart:convert'; import 'dart:io'; import 'package:flutter_custom_clippers/flutter_custom_clippers.dart'; import 'package:form_field_validator/form_field_validator.dart'; import 'package:data_connection_checker/data_connection_checker.dart'; import 'package:giffy_dialog/giffy_dialog.dart'; import 'package:bottom_navy_bar/bottom_navy_bar.dart'; String token = ''; String type = ''; String name = ''; Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); SharedPreferences preferences = await SharedPreferences.getInstance(); token = preferences.getString('Loggedin'); type = preferences.getString('type'); name = preferences.getString('name'); print(token); print(type); runApp(MaterialApp( home: SplashScreen(), )); } class SplashScreen extends StatefulWidget { @override _SplashScreenState createState() => _SplashScreenState(); } class _SplashScreenState extends State<SplashScreen> { @override Widget build(BuildContext context) { return CustomSplash( imagePath: 'images/logo.png', backGroundColor: Color(0xff131535), animationEffect: 'zoom-out', logoSize: 200, home: token == null ? Login() : Home(), duration: 4000, ); } } class Intro extends StatefulWidget { @override _IntroState createState() => _IntroState(); } class _IntroState extends State<Intro> { @override Widget build(BuildContext context) { return Container(); } } class Home extends StatefulWidget { @override _HomeState createState() => _HomeState(); } class _HomeState extends State<Home> { @override void initState() { if (type == 'representative') { Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => RepresentativeUi())); } else if (type == 'student') { Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => StudentUi())); } super.initState(); } @override Widget build(BuildContext context) { return Container( child: Text('hello'), ); } } class Login extends StatefulWidget { @override _LoginState createState() => _LoginState(); } class _LoginState extends State<Login> { TextEditingController email = TextEditingController(); TextEditingController pass = TextEditingController(); final _key = GlobalKey<FormState>(); bool _secureText = true; showHide() { setState(() { _secureText = !_secureText; }); } check() { final form = _key.currentState; if (form.validate()) { form.save(); _login(); } } Future<List> _login() async { final response = await http.post('http://msc-mu.com/login_app.php', body: { 'email': email.text, 'password': pass.text, }); final userdata = json.decode(response.body); String emailAPI = userdata[0]['email']; String nameAPI = userdata[0]['name']; String id = userdata[0]['id']; String year = userdata[0]['year']; String type = userdata[0]['type']; setState(() { savePref(token, emailAPI, nameAPI, id, year, type); print(savePref(token, emailAPI, nameAPI, id, year, type)); }); if (userdata.length == 0) { setState(() { toast('Login Failed'); }); } else if (type == 'representative') { toast('Successfully Logged in'); Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => RepresentativeUi())); } else if (type == 'student') { toast('Successfully Logged in'); Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => StudentUi())); } return userdata; } String token = 'Logged in'; savePref(String token, String email, String name, String id, String year, String type) async { SharedPreferences preferences = await SharedPreferences.getInstance(); setState(() { preferences.setString('Loggedin', token); preferences.setString('name', name); preferences.setString('email', email); preferences.setString('id', id); preferences.setString('year', year); preferences.setString('type', type); preferences.commit(); }); } @override void initState() { var listener = DataConnectionChecker(); listener.onStatusChange.listen((status) { switch (status) { case DataConnectionStatus.connected: toast('Connected'); break; case DataConnectionStatus.disconnected: showDialog( context: context, builder: (context) => AssetGiffyDialog( image: Image.asset('images/wait_connection.gif'), title: Text( 'Your are not Connected', style: TextStyle( fontSize: 22.0, fontWeight: FontWeight.w600), ), description: Text( 'please reconnect your phone to the internet and press OK', textAlign: TextAlign.center, ), entryAnimation: EntryAnimation.TOP_RIGHT, onOkButtonPressed: () { setState(() { void check() async { try { final result = await InternetAddress.lookup('google.com'); if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) { Navigator.pop(context, true); } } on SocketException catch (_) { toast('Still not connected'); } } check(); }); }, onCancelButtonPressed: () {}, )); break; } }); super.initState(); } @override Widget build(BuildContext context) { return Scaffold( body: SingleChildScrollView( child: Container( height: MediaQuery.of(context).size.height, child: Column( children: <Widget>[ ClipPath( clipper: OvalBottomBorderClipper(), child: Image( image: AssetImage('images/logo1.png'), width: double.infinity, height: MediaQuery.of(context).size.height / 3.5, fit: BoxFit.cover, ), ), SizedBox( height: 10.0, ), Form( key: _key, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ SizedBox( height: 80.0, ), Card( elevation: 6.0, child: TextFormField( controller: email, style: TextStyle( color: Colors.black, fontSize: 16, fontWeight: FontWeight.w300, ), decoration: InputDecoration( prefixIcon: Padding( padding: EdgeInsets.only(left: 20, right: 15), child: Icon(Icons.person, color: Colors.black), ), contentPadding: EdgeInsets.all(18), labelText: "Email"), ), ), SizedBox( height: 12.0, ), Card( elevation: 6.0, child: TextFormField( validator: MultiValidator([ RequiredValidator(errorText: 'Password is required'), MinLengthValidator(8, errorText: 'Password must be at least 8 digits long') ]), obscureText: _secureText, controller: pass, style: TextStyle( color: Colors.black, fontSize: 16, fontWeight: FontWeight.w300, ), decoration: InputDecoration( labelText: "Password", prefixIcon: Padding( padding: EdgeInsets.only(left: 20, right: 15), child: Icon(Icons.phonelink_lock, color: Colors.black), ), suffixIcon: IconButton( onPressed: showHide, icon: Icon(_secureText ? Icons.visibility_off : Icons.visibility), ), contentPadding: EdgeInsets.all(18), ), ), ), SizedBox( height: 50.0, ), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ SizedBox( width: 150.0, height: 44.0, child: RaisedButton( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15.0)), child: Text( "Login", style: TextStyle(fontSize: 18.0), ), textColor: Colors.white, color: Theme.of(context).primaryColor, onPressed: () { setState(() { check(); }); }), ), SizedBox( width: 150.0, height: 44.0, child: RaisedButton( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15.0)), child: Text( "GoTo Register", style: TextStyle(fontSize: 18.0), ), textColor: Colors.white, color: Theme.of(context).primaryColor, onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => Register()), ); }), ), ], ), ], ), ), ], ), ), ), ); } } class Register extends StatefulWidget { @override _RegisterState createState() => _RegisterState(); } class _RegisterState extends State<Register> { TextEditingController email = TextEditingController(); TextEditingController password = TextEditingController(); TextEditingController name = TextEditingController(); TextEditingController year = TextEditingController(); TextEditingController type = TextEditingController(); final _key = GlobalKey<FormState>(); bool _secureText = true; showHide() { setState(() { _secureText = !_secureText; }); } check() { final form = _key.currentState; if (form.validate()) { form.save(); register(); } } void register() async { http.post('http://msc-mu.com/register.php', body: { 'email': email.text, 'password': password.text, 'name': name.text, 'year': year.text, 'type': type.text }); } String _selectYear; List years = List(); Future getYears() async { final response = await http.get('http://msc-mu.com/getYears.php'); var resBody = json.decode(response.body); setState(() { years = resBody; }); } String _selectType; List types = List(); Future getTypes() async { var response = await http.post('http://msc-mu.com/getlevel.php'); var resBody = json.decode(response.body); setState(() { types = resBody; }); } @override void initState() { super.initState(); this.getYears(); this.getTypes(); year.text = _selectYear; type.text = _selectType; } @override Widget build(BuildContext context) { return Scaffold( body: SingleChildScrollView( child: Container( height: MediaQuery.of(context).size.height, child: Column( children: <Widget>[ ClipPath( clipper: OvalBottomBorderClipper(), child: Image( image: AssetImage('images/logo1.png'), width: double.infinity, height: MediaQuery.of(context).size.height / 3.5, fit: BoxFit.cover, ), ), Form( key: _key, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ SizedBox( height: 25.0, ), Card( elevation: 6.0, child: TextFormField( controller: name, validator: MinLengthValidator(8, errorText: ('Name must be at least 8 digit long')), style: TextStyle( color: Colors.black, fontSize: 16, fontWeight: FontWeight.w300, ), decoration: InputDecoration( prefixIcon: Padding( padding: EdgeInsets.only(left: 20, right: 15), child: Icon(Icons.person, color: Colors.black), ), contentPadding: EdgeInsets.all(18), labelText: "FullName"), ), ), Card( elevation: 6.0, child: TextFormField( controller: email, validator: EmailValidator( errorText: 'Please enter a valid email address'), style: TextStyle( color: Colors.black, fontSize: 16, fontWeight: FontWeight.w300, ), decoration: InputDecoration( prefixIcon: Padding( padding: EdgeInsets.only(left: 20, right: 15), child: Icon(Icons.email, color: Colors.black), ), contentPadding: EdgeInsets.all(18), labelText: "Email"), ), ), Card( elevation: 6.0, child: TextFormField( controller: password, validator: MultiValidator([ RequiredValidator(errorText: 'Password is Required'), MinLengthValidator(8, errorText: 'Password must be at least 8 digit long') ]), obscureText: _secureText, style: TextStyle( color: Colors.black, fontSize: 16, fontWeight: FontWeight.w300, ), decoration: InputDecoration( suffixIcon: IconButton( onPressed: showHide, icon: Icon(_secureText ? Icons.visibility_off : Icons.visibility), ), prefixIcon: Padding( padding: EdgeInsets.only(left: 20, right: 15), child: Icon(Icons.phonelink_lock, color: Colors.black), ), contentPadding: EdgeInsets.all(18), labelText: "Password"), ), ), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[ Card( elevation: 6.0, child: DropdownButton<String>( hint: Text('Choose your role'), icon: Icon(Icons.arrow_drop_down), iconSize: 24.0, elevation: 16, style: TextStyle(color: Colors.black, fontSize: 16.0), underline: Container( height: 2, color: Theme.of(context).primaryColor, ), items: types.map((item) { return DropdownMenuItem( child: Text(item['Levelname']), value: item['Levelname'].toString(), ); }).toList(), onChanged: (newVal) { setState(() { _selectType = newVal; type.text = _selectType; }); }, value: _selectType, ), ), Card( elevation: 6.0, child: DropdownButton<String>( hint: Text('Choose your Year'), icon: Icon(Icons.arrow_drop_down), iconSize: 24.0, elevation: 16, style: TextStyle(color: Colors.black, fontSize: 16.0), underline: Container( height: 2, color: Theme.of(context).primaryColor, ), items: years.map((item) { return DropdownMenuItem( child: Text(item['name']), value: item['name'].toString(), ); }).toList(), onChanged: (newVal) { setState(() { _selectYear = newVal; year.text = _selectYear; }); }, value: _selectYear, ), ), ], ), SizedBox( height: 20.0, ), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ SizedBox( width: 150.0, height: 44.0, child: RaisedButton( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15.0)), child: Text( "Register", style: TextStyle(fontSize: 18.0), ), textColor: Colors.white, color: Theme.of(context).primaryColor, onPressed: () { setState(() { check(); toast( 'Successfully Registered , Can you please Login again ? '); Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => Login())); }); }), ), SizedBox( width: 150.0, height: 44.0, child: RaisedButton( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15.0)), child: Text( "GoTo Login", style: TextStyle(fontSize: 18.0), ), textColor: Colors.white, color: Theme.of(context).primaryColor, onPressed: () { setState(() { Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => Login())); }); }), ), ], ), ], ), ), ], ), ), ), ); } } class RepresentativeUi extends StatefulWidget { @override _RepresentativeUiState createState() => _RepresentativeUiState(); } class _RepresentativeUiState extends State<RepresentativeUi> { int _currentIndex = 0; // navy bottom pages final _newsFeedPage = RNewsFeed(); final _profilePage = RProfile(); final _addPostPage = RAddPost(); final _libraryPage = RLibrary(); Widget _showPage = RNewsFeed(); Widget _pageChooser(int page) { switch (page) { case 0: return _newsFeedPage; break; case 1: return _addPostPage; break; case 2: return _libraryPage; break; case 3: return _profilePage; break; } } @override Widget build(BuildContext context) { return Scaffold( bottomNavigationBar: CurvedNavigationBar( index: _currentIndex, items: <Widget>[ Icon( FontAwesomeIcons.newspaper, size: 30, ), Icon( FontAwesomeIcons.plus, size: 30, ), Icon( FontAwesomeIcons.book, size: 30, ), Icon( FontAwesomeIcons.user, size: 30, ), ], color: Colors.white, buttonBackgroundColor: Colors.white, backgroundColor: Color(0xff131535), animationCurve: Curves.easeIn, animationDuration: Duration(milliseconds: 400), onTap: (int tappedIndex) { setState(() { _showPage = _pageChooser(tappedIndex); }); }, ), body: Container( child: _showPage, ), ); } } class RProfile extends StatefulWidget { @override _RProfileState createState() => _RProfileState(); } class _RProfileState extends State<RProfile> { String _name ,_email , _class , _level ; getPref() async { SharedPreferences preferences = await SharedPreferences.getInstance(); setState(() { _name = preferences.getString('name'); _email = preferences.getString('email'); _class = preferences.getString('year'); _level = preferences.getString('level'); }); } @override void initState() { super.initState(); getPref(); } @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: Column( ), Text( '_name', style: TextStyle( fontSize: 40.0, color: Colors.white, fontWeight: FontWeight.bold, fontFamily: 'Pacifico', ),
if the proplem was with initstat and setstate why it did not bring up any error before as you can see i did it several times before ! so what should i do ?
-
Nada Khaled over 3 yearsThanks for making that clear but can i know where is the error exactly and why it tells me that its in material app in main ?
-
griffins over 3 yearsi have updated my answer also check link posted in answer will answer why
-
Nada Khaled over 3 yearsThanks you sooo much , is that code my only issue ?
-
griffins over 3 yearshavent checked all lines,I'll check and get back to you , do mark as answer if it worked for you.Thanks
-
Mohammed Ali over 2 yearsyou made my day!