I am new to flutter and facing an issue in Syncfusion Calendar widget. Any help will be appreciated. Here is the code inside my build widget:
return Scaffold(
resizeToAvoidBottomInset: false, // set it to false
body: SafeArea(
child: SfCalendar(
view: CalendarView.month,
dataSource:getData(),
monthViewSettings: MonthViewSettings(showAgenda: true,),
),
),
);
'dart:ui/painting.dart': Failed assertion: line 1205 pos 12: '': is not true.
Here is the exception line:4 > child: SfCalendar()
Here is the stacktrace:
**> The relevant error-causing widget was: SfCalendar
file:///Users/kashif/Desktop/AppRack/clique/lib/bottomDashboard/Calendar.dart:47:16
When the exception was thrown, this was the stack:
#2 Paint.color= (dart:ui/painting.dart:1205:12)
#3 _AppointmentRenderObject._drawMonthAppointmentIndicator (package:syncfusion_flutter_calendar/src/calendar/appointment_layout/appointment_layout.dart:2042:15)
#4 _AppointmentRenderObject._drawMonthAppointment (package:syncfusion_flutter_calendar/src/calendar/appointment_layout/appointment_layout.dart:1698:9)
#5 _AppointmentRenderObject._drawCustomAppointmentView (package:syncfusion_flutter_calendar/src/calendar/appointment_layout/appointment_layout.dart:1662:11)
#6 _AppointmentRenderObject.paint (package:syncfusion_flutter_calendar/src/calendar/appointment_layout/appointment_layout.dart:1614:7)
#7 RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2396:7)
#8 PaintingContext._repaintCompositedChild (package:flutter/src/rendering/object.dart:139:11)
#9 PaintingContext.repaintCompositedChild (package:flutter/src/rendering/object.dart:100:5)
#10 PipelineOwner.flushPaint (package:flutter/src/rendering/object.dart:975:29)
#11 RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:464:19)
#12 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:879:13)
#13 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:328:5)
#14 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1143:15)
#15 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1080:9)
#16 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:996:5)
#20 _invoke (dart:ui/hooks.dart:163:10)
#21 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:259:5)
#22 _drawFrame (dart:ui/hooks.dart:126:31) (elided 5 frames from class _AssertionError and dart:async) The following RenderObject was
being processed when the exception was fired:
_AppointmentRenderObject#b4ead ... needs compositing ... parentData: (can use size) ... constraints: BoxConstraints(w=411.4,
h=452.8) ... layer: OffsetLayer#2d0bc ... engine layer:
OffsetEngineLayer#fc8e9 ... offset: Offset(0.0, 0.0) ... size:
Size(411.4, 452.8) RenderObject: _AppointmentRenderObject#b4ead
needs compositing parentData: (can use size) constraints:
BoxConstraints(w=411.4, h=452.8) layer: OffsetLayer#2d0bc
engine layer: OffsetEngineLayer#fc8e9
offset: Offset(0.0, 0.0) size: Size(411.4, 452.8)
====================================================================================================**
Based on the provided information we have checked, and we could not reproduce the mentioned issue from our end. We have prepared a simple sample for the same, based on the given stack, we suspect that appointment color set as null in the sample. Please find the code snippet for the same.
Code snippet:
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:syncfusion_flutter_calendar/calendar.dart';
void main() => runApp(AgendaView());
class AgendaView extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Agenda(),
);
}
}
class Agenda extends StatefulWidget {
#override
State<StatefulWidget> createState() => AgendaExample();
}
class AgendaExample extends State<Agenda> {
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: SafeArea(
child: SfCalendar(
view: CalendarView.month,
dataSource: MeetingDateSource(_getDataSource()),
monthViewSettings: MonthViewSettings(showAgenda: true),
),
),
);
}
}
List<Meeting> _getDataSource() {
List<Meeting> meets = <Meeting>[];
meets.add(Meeting('Meeting', DateTime.now(),
DateTime.now().add(Duration(minutes: 30)), Colors.pink, true));
return meets;
}
class MeetingDateSource extends CalendarDataSource {
MeetingDateSource(List<Meeting> source) {
appointments = source;
}
#override
String getSubject(int index) {
return appointments![index].eventname;
}
#override
DateTime getStartTime(int index) {
return appointments![index].from;
}
#override
DateTime getEndTime(int index) {
return appointments![index].to;
}
#override
Color getColor(int index) {
return appointments![index].bgclr;
}
#override
bool isAllDay(int index) {
return appointments![index].bval;
}
}
class Meeting {
Meeting(this.eventname, this.from, this.to, this.bgclr, this.bval);
String eventname;
DateTime from;
DateTime to;
Color bgclr;
bool bval;
}
If the shared information does not meet your requirement, could you please modify the shared sample to replicate the issue or if possible, share the calendar code snippets used with replication procedure, so that we could analyze further and provide you a possible solution at the earliest.
Related
I added a new field to the class CloudNote, now I am getting an error!
I am getting the error when the app is trying to display a list.
Here is all my code without adding the field :: https://github.com/casas1010/flutter_firebase_vendor_management
I know its a simple issue, but I have tried to troubleshoot this for like an hour and have not made any progress
CloudNote class::
import 'package:cloud_firestore/cloud_firestore.dart';
import '/services/cloud/cloud_storage_constants.dart';
import 'package:flutter/foundation.dart';
/*
https://youtu.be/VPvVD8t02U8?t=87934
*/
#immutable
class CloudNote {
final String documentId;
final String jobCreatorId;
final String jobDescription;
final String jobState; // I added this
const CloudNote({
required this.documentId,
required this.jobCreatorId,
required this.jobDescription,
required this.jobState, // I added this
});
// acts as constructor
CloudNote.fromSnapshot(QueryDocumentSnapshot<Map<String, dynamic>> snapshot)
: documentId = snapshot.id,
jobCreatorId = snapshot.data()[jobCreatorIdColumn],
jobState = snapshot.data()[jobStateColumn], // I added this
jobDescription = snapshot.data()[jobDescriptionColumn] as String;
}
notes view ::
import 'package:flutter/material.dart';
import '/constants/routes.dart';
import '/enums/menu_action.dart';
import '/services/auth/auth_service.dart';
import '/services/cloud/cloud_note.dart';
import '/services/cloud/firebase_cloud_storage.dart';
import '/utilities/dialogs/logout_dialog.dart';
import '/views/notes/notes_list_view.dart';
class NotesView extends StatefulWidget {
const NotesView({Key? key}) : super(key: key);
#override
_NotesViewState createState() => _NotesViewState();
}
class _NotesViewState extends State<NotesView> {
late final FirebaseCloudStorage _notesService;
String get userId => AuthService.firebase().currentUser!.id;
#override
void initState() {
_notesService = FirebaseCloudStorage();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Your jobs'),
actions: [
IconButton(
onPressed: () {
Navigator.of(context).pushNamed(createOrUpdateNoteRoute);
},
icon: const Icon(Icons.add),
),
PopupMenuButton<MenuAction>(
onSelected: (value) async {
switch (value) {
case MenuAction.logout:
final shouldLogout = await showLogOutDialog(context);
if (shouldLogout) {
await AuthService.firebase().logOut();
Navigator.of(context).pushNamedAndRemoveUntil(
loginRoute,
(_) => false,
);
}
}
},
itemBuilder: (context) {
return const [
PopupMenuItem<MenuAction>(
value: MenuAction.logout,
child: Text('Log out'),
),
];
},
)
],
),
body: StreamBuilder(
stream: _notesService.allNotes(jobCreatorId: userId),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
case ConnectionState.active:
if (snapshot.hasData) {
final allNotes = snapshot.data as Iterable<CloudNote>;
return NotesListView(
notes: allNotes,
onDeleteNote: (note) async {
await _notesService.deleteNote(documentId: note.documentId);
},
onTap: (note) {
Navigator.of(context).pushNamed(
createOrUpdateNoteRoute,
arguments: note,
);
},
);
} else {
return const CircularProgressIndicator();
}
default:
return const CircularProgressIndicator();
}
},
),
);
}
}
Error
The following _TypeError was thrown building NotesListView(dirty):
type 'Null' is not a subtype of type 'String'
The relevant error-causing widget was
NotesListView
lib/…/notes/notes_view.dart:72
When the exception was thrown, this was the stack
#0 new CloudNote.fromSnapshot
package:ijob_clone_app/…/cloud/cloud_note.dart:26
#1 FirebaseCloudStorage.allNotes.<anonymous closure>.<anonymous closure>
package:ijob_clone_app/…/cloud/firebase_cloud_storage.dart:39
#2 MappedListIterable.elementAt (dart:_internal/iterable.dart:413:31)
#3 ListIterator.moveNext (dart:_internal/iterable.dart:342:26)
#4 WhereIterator.moveNext (dart:_internal/iterable.dart:438:22)
#5 Iterable.length (dart:core/iterable.dart:497:15)
#6 NotesListView.build
package:ijob_clone_app/…/notes/notes_list_view.dart:26
#7 StatelessElement.build
package:flutter/…/widgets/framework.dart:4949
#8 ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4878
#9 Element.rebuild
package:flutter/…/widgets/framework.dart:4604
#10 ComponentElement._firstBuild
package:flutter/…/widgets/framework.dart:4859
#11 ComponentElement.mount
package:flutter/…/widgets/framework.dart:4853
#12 Element.inflateWidget
package:flutter/…/widgets/framework.dart:3863
#13 Element.updateChild
package:flutter/…/widgets/framework.dart:3586
#14 ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4904
#15 StatefulElement.performRebuild
package:flutter/…/widgets/framework.dart:5050
#16 Element.rebuild
package:flutter/…/widgets/framework.dart:4604
#17 BuildOwner.buildScope
package:flutter/…/widgets/framework.dart:2667
#18 WidgetsBinding.drawFrame
package:flutter/…/widgets/binding.dart:882
#19 RendererBinding._handlePersistentFrameCallback
package:flutter/…/rendering/binding.dart:378
#20 SchedulerBinding._invokeFrameCallback
package:flutter/…/scheduler/binding.dart:1175
#21 SchedulerBinding.handleDrawFrame
package:flutter/…/scheduler/binding.dart:1104
#22 SchedulerBinding._handleDrawFrame
package:flutter/…/scheduler/binding.dart:1015
#23 _invoke (dart:ui/hooks.dart:148:13)
#24 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:318:5)
#25 _drawFrame (dart:ui/hooks.dart:115:31)
════════════════════════════════════════════════════════════════════════════════
NotesListView ::
import 'package:flutter/material.dart';
import '/services/cloud/cloud_note.dart';
import '/utilities/dialogs/delete_dialog.dart';
/*
source: https://www.youtube.com/watch?v=VPvVD8t02U8&t=59608s
class creation :: 22:02:54
*/
typedef NoteCallback = void Function(CloudNote note);
class NotesListView extends StatelessWidget {
final Iterable<CloudNote> notes; // list of notes
final NoteCallback onDeleteNote;
final NoteCallback onTap;
const NotesListView({
Key? key,
required this.notes,
required this.onDeleteNote,
required this.onTap,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: notes.length,
itemBuilder: (context, index) {
final note =
notes.elementAt(index); // current note whose data we are returning
return ListTile(
onTap: () {
onTap(note);
},
title: Text(
note.jobDescription,
maxLines: 1,
softWrap: true,
overflow: TextOverflow.ellipsis,
),
trailing: IconButton(
onPressed: () async {
final shouldDelete = await showDeleteDialog(context);
if (shouldDelete) {
onDeleteNote(note);
}
},
icon: const Icon(Icons.delete),
),
);
},
);
}
}
This happens if you forget to update your Firestore entries. Atleast one of your CloudNote entries in Firestore does not have the field jobState. That's why Firestore returns a Null value. But it tries to map to String which leads to an exception.
Make sure to rerun the project.
or
flutter clean
and then
flutter run
I already went through few posts (like this, this, etc) mentioning the same error but their solutions didn't work.
Minimal reproducible code:
class MyPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: ElevatedButton(
onPressed: () => Navigator.push(context, MyRoute(child: Page2())),
child: Text('Navigate'),
),
);
}
}
class MyRoute extends PageRouteBuilder {
final Widget child;
MyRoute({this.child}) : super(pageBuilder: (_, __, ___) => child);
#override
Widget buildTransitions(_, __, ___, ____) {
return Stack(
children: [
Positioned(
left: 0,
child: child, // Doesn't work
// child: FlutterLogo(size: 100), // Works
),
],
);
}
}
class Page2 extends StatelessWidget {
#override
Widget build(BuildContext context) => Scaffold(appBar: AppBar(title: Text('Page 2')));
}
The problem is happening in the buildTransitions() method when I return child in Positioned. However, returning other widgets like a FlutterLogo does seem to work.
The following assertion was thrown during performLayout():
RenderCustomMultiChildLayoutBox object was given an infinite size during layout.
I tried wrapping my Stack in a SizedBox but that didn't work.
Note: I know I can simply return child and do other such things like setting right, top and bottom property to 0 in Positioned, but my question isn't about solving it, but rather why there's an error, what's causing the infinite size?
Edit (added stack trace)
[ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: 'package:flutter/src/rendering/box.dart': Failed assertion: line 2773 pos 18: 'transformed == position - childParentData.offset': is not true.
#0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:46:39)
#1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5)
#2 RenderBoxContainerDefaultsMixin.defaultHitTestChildren.<anonymous closure> (package:flutter/src/rendering/box.dart:2773:18)
#3 BoxHitTestResult.addWithPaintOffset (package:flutter/src/rendering/box.dart:786:31)
#4 RenderBoxContainerDefaultsMixin.defaultHitTestChildren (package:flutter/src/rendering/box.dart:2769:33)
#5 RenderStack.hitTestChildren (package:flutter/src/rendering/stack.dart:620:12)
#6 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2413:11)
#7 RenderProxyBoxMixin.hitTestChildren (package:flutter/src/rendering/proxy_box.dart:131:19) <37 more lines>
I have a problem with Admob's widgets.
I am developing a new feature for a flutter app that contains an Admob banner widget.
But when I setState the value of another widget, the Admob Widget gets an error.
I am using :google_mobile_ads: ^0.11.0+1
The banner is build like so:
#override
void initState() {
setState(() {
_adBanner = createBannerAd();
});
super.initState();
}
#override
void dispose() {
_adBanner.dispose();
super.dispose();
}
And the widget is display like this:
Container(
margin: EdgeInsets.only(bottom: myPercent(2, screenHeight)),
child: FutureBuilder(
future: _adBanner.load(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Container(
margin: EdgeInsets.only(bottom: 3),
width: myPercent(95, screenWidth),
height: myPercent(6, screenHeight),
alignment: Alignment.center,
child: AdWidget(
ad: _adBanner,
),
);
}
return Container();
}),
The log error catch :
flutter: click
flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
flutter: The following assertion was thrown building AdWidget(dirty, state: _AdWidgetState#a1afb):
flutter: This AdWidget is already in the Widget tree
flutter: If you placed this AdWidget in a list, make sure you create a new instance in the builder function
flutter: with a unique ad object.
flutter: Make sure you are not using the same ad object in more than one AdWidget.
flutter:
flutter: The relevant error-causing widget was:
flutter: AdWidget file:///Users/sofian/Work/Personal/Mobile/WhatUDo/what_u_do/lib/views/idea.dart:295:34
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0 _AdWidgetState.build (package:google_mobile_ads/src/ad_containers.dart:372:7)
flutter: #1 StatefulElement.build (package:flutter/src/widgets/framework.dart:4825:27)
flutter: #2 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4708:15)
flutter: #3 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4880:11)
flutter: #4 BuildOwner._runWithCurrentBuildTarget (package:flutter/src/widgets/framework.dart:2708:15)
flutter: #5 Element.rebuild (package:flutter/src/widgets/framework.dart:4407:12)
flutter: #6 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4687:5)
flutter: #7 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4871:11)
flutter: #8 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4682:5)
flutter: ... Normal element mounting (10 frames)
flutter: #18 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3660:14)
flutter: #19 Element.updateChild (package:flutter/src/widgets/framework.dart:3422:20)
flutter: #20 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4733:16)
flutter: #21 BuildOwner._runWithCurrentBuildTarget (package:flutter/src/widgets/framework.dart:2708:15)
flutter: #22 Element.rebuild (package:flutter/src/widgets/framework.dart:4407:12)
flutter: #23 StatelessElement.update (package:flutter/src/widgets/framework.dart:4789:5)
flutter: #24 Element.updateChild (package:flutter/src/widgets/framework.dart:3412:15)
flutter: #25 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4733:16)
flutter: #26 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4880:11)
flutter: #27 BuildOwner._runWithCurrentBuildTarget (package:flutter/src/widgets/framework.dart:2708:15)
flutter: #28 Element.rebuild (package:flutter/src/widgets/framework.dart:4407:12)
flutter: #29 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2813:33)
flutter: #30 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:899:21)
flutter: #31 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:320:5)
flutter: #32 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1119:15)
flutter: #33 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1057:9)
flutter: #34 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:973:5)
flutter: #38 _invoke (dart:ui/hooks.dart:157:10)
flutter: #39 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:253:5)
flutter: #40 _drawFrame (dart:ui/hooks.dart:120:31)
flutter: (elided 3 frames from dart:async)
As from question and error log, seems like you are trying to fresh screen/widget using setState but not the actual ad based container widget - still you are getting this error.
If I understood correctly.. then issue is about ad widget is trying to rebuild on setState call with older ad object but it expect new ad object everytime new build. So, avoid those kind of widget build if that's not required.
create a seprate ad based container widget like AppXyzAdWidget and move the ad's parent container code and other ad related code inside the new widget and use the newly created ad based widget on your screen.
This way you can decouple your screen without ad related things then after setState will not reload your ad and their widget just only refresh your content.
Calling setState() causes the widget to rebuild, so your FutureBuilder() widget fires the future task again. This is why you're seeing this error.
You need to remove FutureBuilder() and move your future task to initState():
// ...
// Some code
#override
void initState() {
setState(() {
_adBanner = createBannerAd();
});
_adBanner.load().whenComplete(() {
if (this.mounted) {
setState(() {
_showAdBanner = true;
});
}
});
super.initState();
}
#override
void dispose() {
_adBanner.dispose();
super.dispose();
}
// ...
// Some code
You can also have boolean to make the AdWidget() appear when the future task is complete:
bool _showAdBanner = false;
// ...
// Some code
_showAdBanner
? Container(
margin: EdgeInsets.only(bottom: 3),
width: myPercent(95, screenWidth),
height: myPercent(6, screenHeight),
alignment: Alignment.center,
child: AdWidget(
ad: _adBanner,
),
)
: Container()
// ...
// Some code
According to the google ads package example
googleads-mobile-flutter
You have to use didChangeDependencies
class BannarAdWidget extends StatefulWidget {
const BannarAdWidget({Key? key}) : super(key: key);
#override
State<BannarAdWidget> createState() => _BannarAdWidgetState();
}
class _BannarAdWidgetState extends State<BannarAdWidget> {
BannerAd? _bannerAd;
bool _bannerAdIsLoaded = false;
#override
void didChangeDependencies() {
// Create the ad objects and load ads.
_bannerAd = BannerAd(
size: AdSize.banner,
request: const AdRequest(),
adUnitId: AdmobHelper.bannerAdUnitId,
listener: BannerAdListener(
onAdLoaded: (Ad ad) {
print('$BannerAd loaded.');
setState(() => _bannerAdIsLoaded = true);
},
onAdFailedToLoad: (Ad ad, LoadAdError error) {
print('$BannerAd failedToLoad: $error');
ad.dispose();
},
onAdOpened: (Ad ad) => print('$BannerAd onAdOpened.'),
onAdClosed: (Ad ad) => print('$BannerAd onAdClosed.'),
),
)..load();
super.didChangeDependencies();
}
#override
void dispose() {
_bannerAd?.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
final BannerAd? bannerAd = _bannerAd;
if (_bannerAdIsLoaded && bannerAd != null) {
return SizedBox(
height: bannerAd.size.height.toDouble(),
width: bannerAd.size.width.toDouble(),
child: AdWidget(ad: bannerAd),
);
} else {
return const SizedBox.shrink();
}
}
class AdmobHelper {
static String get bannerAdUnitId {
if (Platform.isAndroid) {
return "ca-app-pub-3940256099942544/6300978111";
} else if (Platform.isIOS) {
return "ca-app-pub-3940256099942544/2934735716";
} else {
throw UnsupportedError('Unsupported platform');
}
}
}
Can you remove initState code and initialize _adBanner in your build function like this ?
#override
Widget build(BuildContext context) {
_adBanner = createBannerAd();
return Container(
margin: EdgeInsets.only(bottom: myPercent(2, screenHeight)),
child: FutureBuilder(
future: _adBanner.load(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Container(
margin: EdgeInsets.only(bottom: 3),
width: myPercent(95, screenWidth),
height: myPercent(6, screenHeight),
alignment: Alignment.center,
child: AdWidget(
ad: _adBanner,
),
);
}
return Container();
});
}
This is my code and the error I'm getting in Visual Studio Code. It used to work before, not sure if an update messed it up. I have other Flutter programs running just fine, not sure what the problem is with this one.
// 1) Create a new Flutter App (in this project) and output an AppBar and some text
// below it
// 2) Add a button which changes the text (to any other text of your choice)
// 3) Split the app into three widgets: App, TextControl & Text
import 'dart:math';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
// void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _MyAppState();
}
}
class _MyAppState extends State<MyApp> {
Random _stringIndex = new Random();
var _randomStringIndex;
final _strings = const [
"Hello",
"This is a string",
"This is random",
];
void _changeText() {
setState(() {
_randomStringIndex = _stringIndex.nextInt(_strings.length);
});
print(_strings[_randomStringIndex]);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('My First App'),
),
body: Center(
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RaisedButton(
onPressed: _changeText,
),
Text(
_strings[_randomStringIndex],
),
],
),
),
),
),
);
}
}
Launching lib/main.dart on Android SDK built for x86 in debug mode...
✓ Built build/app/outputs/apk/debug/app-debug.apk. Connecting to VM
Service at ws://127.0.0.1:40605/I0TqLbk5jw4=/ws D/EGL_emulation(
7151): eglMakeCurrent: 0xe1b1a3c0: ver 2 0 (tinfo 0xe1b0f770)
D/eglCodecCommon( 7151): setVertexArrayObject: set vao to 0 (0) 1 0
I/flutter ( 7151): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY
╞═══════════════════════════════════════════════════════════ I/flutter
( 7151): The following ArgumentError was thrown building MyApp(dirty,
state: _MyAppState#202c3): I/flutter ( 7151): Invalid argument(s)
I/flutter ( 7151): I/flutter ( 7151): The relevant error-causing
widget was: I/flutter ( 7151): MyApp I/flutter ( 7151):
package:flutter_assignment/main.dart:11 I/flutter ( 7151): I/flutter (
7151): When the exception was thrown, this was the stack: I/flutter (
7151): #0 List.[] (dart:core-patch/array.dart:169:52) I/flutter
( 7151): #1 _MyAppState.build
package:flutter_assignment/main.dart:57 I/flutter ( 7151): #2
StatefulElement.build package:flutter/…/widgets/framework.dart:4619
I/flutter ( 7151): #3 ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4502 I/flutter ( 7151): #4
StatefulElement.performRebuild
package:flutter/…/widgets/framework.dart:4675 I/flutter ( 7151): #5
Element.rebuild package:flutter/…/widgets/framework.dart:4218
I/flutter ( 7151): #6 ComponentElement._firstBuild
package:flutter/…/widgets/framework.dart:4481 I/flutter ( 7151): #7
StatefulElement._firstBuild
package:flutter/…/widgets/framework.dart:4666 I/flutter ( 7151): #8
ComponentElement.mount package:flutter/…/widgets/framework.dart:4476
I/flutter ( 7151): #9 Element.inflateWidget
package:flutter/…/widgets/framework.dart:3446 I/flutter ( 7151): #10
Element.updateChild package:flutter/…/widgets/framework.dart:3214
I/flutter ( 7151): #11 RenderObjectToWidgetElement._rebuild
package:flutter/…/widgets/binding.dart:1148 I/flutter ( 7151): #12
RenderObjectToWidgetElement.mount
package:flutter/…/widgets/binding.dart:1119 I/flutter ( 7151): #13
RenderObjectToWidgetAdapter.attachToRenderTree.
package:flutter/…/widgets/binding.dart:1061 I/flutter ( 7151): #14
BuildOwner.buildScope package:flutter/…/widgets/framework.dart:2607
I/flutter ( 7151): #15
RenderObjectToWidgetAdapter.attachToRenderTree
package:flutter/…/widgets/binding.dart:1060 I/flutter ( 7151): #16
WidgetsBinding.attachRootWidget
package:flutter/…/widgets/binding.dart:941
You can copy paste run full code below
You need to init _randomStringIndex
code snippet
var _randomStringIndex = 0;
working demo
full code
import 'dart:math';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
// void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _MyAppState();
}
}
class _MyAppState extends State<MyApp> {
Random _stringIndex = new Random();
var _randomStringIndex = 0;
final _strings = const [
"Hello",
"This is a string",
"This is random",
];
void _changeText() {
setState(() {
_randomStringIndex = _stringIndex.nextInt(_strings.length);
});
print(_strings[_randomStringIndex]);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('My First App'),
),
body: Center(
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RaisedButton(
onPressed: _changeText,
),
Text(
_strings[_randomStringIndex],
),
],
),
),
),
),
);
}
}
Try to run this command inside your project (terminal):
flutter clean
and then run it again!
I created a flutter project with provider package
Previously it had run well using ScopedModel following this sample project.
I want to implement v3 provider with the same logic,
// main.dart
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(builder: (context) => NoteContentModel()),
],
...
home: NoteContentPage(),
),
);
}
// note_content_model.dart
class NoteContentModel extends ChangeNotifier {
final _pageSize = 30;
List<Content> _content = [];
bool _isLoading = false;
int _totalResults;
int _totalPages;
bool _hasMorePages = true;
String _placeName;
bool _isLoadingMore = false;
// .. other setter getter
int getNoteCount() => _content.length;
Future<dynamic> _getData([int page = 1]) async {
var res = await http.get(getUrl(page));
return jsonDecode(res.body);
}
Future getNoteContent([int page = 1]) async {
if (page == 1) {
_isLoading = true;
_content.clear();
} else {
_isLoadingMore = true;
}
notifyListeners();
var responseData = await _getData();
List noteContent = responseData['content'];
noteContent.forEach((content) {
_content.add(Content.fromJson(content));
});
_totalResults = responseData['total_count'];
_totalPages = responseData['page_count'];
if (responseData['page_number'] == totalPages) {
_hasMorePages = false;
}
if (page == 1) {
_isLoading = false;
} else {
_isLoadingMore = false;
}
notifyListeners();
}
}
// note_content_page.dart
class NoteContentPage extends StatefulWidget {
#override
_NoteContentPageState createState() => _NoteContentPageState();
}
class _NoteContentPageState extends State<NoteContentPage> {
int page = 1;
ScrollController controller;
void _scrollListener() {
final NoteContentModel noteModel = Provider.of<NoteContentModel>(context);
if (controller.position.pixels == controller.position.maxScrollExtent) {
if (!noteModel.isLoadingMore && noteModel.hasMorePages) {
page++;
print("Current page: $page");
noteModel.getNoteContent(page);
}
}
}
#override
void initState() {
super.initState();
controller = new ScrollController()..addListener(_scrollListener);
}
#override
void dispose() {
super.dispose();
controller.dispose();
}
#override
Widget build(BuildContext context) {
final NoteContentModel noteModel = Provider.of<NoteContentModel>(context);
// Call initiate first page
noteModel.getNoteContent(page);
return Scaffold(
appBar: AppBar(title: Text("Test")),
body: CustomScrollView(
controller: controller,
slivers: <Widget>[
noteModel.isLoading
? SliverFillRemaining(
child: Center(
child: CircularProgressIndicator(),
),
)
: SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
if (index == noteModel.getNoteCount()) {
if (noteModel.hasMorePages) {
print("here1");
return Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: Center(child: CircularProgressIndicator()),
);
}
return Container();
} else {
return Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(noteModel.content[index].title),
// child: Text("test"),
),
],
);
}
},
childCount: noteModel.getNoteCount(),
),
)
],
),
);
}
}
I always got this message loop markNeedsBuild() called during build end trace error
I/flutter ( 2525): ══╡ EXCEPTION CAUGHT BY FOUNDATION LIBRARY ╞════════════════════════════════════════════════════════
I/flutter ( 2525): The following assertion was thrown while dispatching notifications for NoteContentModel:
I/flutter ( 2525): setState() or markNeedsBuild() called during build.
I/flutter ( 2525): This ListenableProvider<NoteContentModel> widget cannot be marked as needing to build because the
...
I/flutter ( 2525): #0 Element.markNeedsBuild.<anonymous closure> (package:flutter/src/widgets/framework.dart:3670:11)
I/flutter ( 2525): #1 Element.markNeedsBuild (package:flutter/src/widgets/framework.dart:3685:6)
I/flutter ( 2525): #2 State.setState (package:flutter/src/widgets/framework.dart:1161:14)
I/flutter ( 2525): #3 __BuilderListenableDelegate&BuilderStateDelegate&_ListenableDelegateMixin.startListening.<anonymous closure> (package:provider/src/listenable_provider.dart:186:36)
I/flutter ( 2525): #4 ChangeNotifier.notifyListeners (package:flutter/src/foundation/change_notifier.dart:206:21)
I/flutter ( 2525): #5 NoteContentModel.getNoteContent (package:paging_provider/providers/note_content_model.dart:42:5)
I/flutter ( 2525): <asynchronous suspension>
I/flutter ( 2525): #6 _NoteContentPageState.build (package:paging_provider/pages/note_content_page.dart:44:15)
I/flutter ( 2525): #7 StatefulElement.build (package:flutter/src/widgets/framework.dart:4012:27)
I/flutter ( 2525): #8 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3924:15)
I/flutter ( 2525): #9 Element.rebuild (package:flutter/src/widgets/framework.dart:3721:5)
I/flutter ( 2525): #10 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3907:5)
...
// This trace always loop on app running
I/flutter ( 2525): Another exception was thrown: setState() or markNeedsBuild() called during build....
so that's all, any response will be appreciated.
You must wrap your functions in addPostFrameCallback():
So the call is submitted after the build function finish it work and draw widgets over screen
//Change
noteModel.getNoteContent(page);
//To
WidgetsBinding.instance.addPostFrameCallback((_) => noteModel.getNoteContent(page);
);
Hope this answer being valuable for someone.