sfcalendar flutter web displays only after screen resize

I read appointment from my data source during initState:

void initialize() async {
// reading from external data source
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) setState(() {});
});
}
@override
initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
initialize();
});
debugPrint('init complete');
}


and then call SfCalendar in my main screen wrappen in a ValueListenableBuilder that reacts to selections in SfCalendar:

Widget build(BuildContext context) {
child: Scaffold(
backgroundColor: myWhite,
resizeToAvoidBottomInset : true,
appBar: PreferredSize(
preferredSize: Size.fromHeight(45),
child: ValueListenableBuilder(
valueListenable: appBarChanges,
builder: (context, value, child) {
return AppBar(
leading: Padding(
padding: const EdgeInsets.all(10.0),
child: Image(image:AssetImage('assets/images/DeBungle logo.png'), height: 32, width: 32),
),
backgroundColor: myWhite,
automaticallyImplyLeading: false,
title: Text((source == 'eventReschedule')? 'Reschedule for this time':'Pick from these available slots', style: headline3Dark),
actions: appBarWidgets(),
);
}
),
),
body: ValueListenableBuilder(
valueListenable: sfCalendarSelectionChanged,
builder: (context, value, child) {
return
    LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return SfCalendar(
controller: _SfCalendarController,
view: CalendarView.schedule,
allowedViews: [
CalendarView.day,
CalendarView.week,
CalendarView.schedule
],
showNavigationArrow: true,
dataSource: _AppointmentDataSource(allOpenSlots), //MeetingDataSource(meetings),
showDatePickerButton: false ,
showTodayButton: true ,
onViewChanged: calendarViewChanged,
allowViewNavigation:true,
appointmentBuilder: _appointmentBuilder,
monthViewSettings: MonthViewSettings(
showAgenda: false,
appointmentDisplayMode: MonthAppointmentDisplayMode.indicator,
showTrailingAndLeadingDates: false,
),
timeSlotViewSettings: TimeSlotViewSettings(
// startHour: 6.0,
// endHour: 21.0,
minimumAppointmentDuration: Duration(minutes: 50),
timeIntervalHeight: 50,
),
);
},

);

),


At first I get a blank body until I resize my window, and then the appointment slots display correctly.

I added the WidegtBinding and SetState based on AI suggestions without any improvements. How can I render SfCalendar with the first call of the build Widget?


5 Replies 1 reply marked as answer

HM Harsha Midadhala Khajareddy Midadhala Syncfusion Team November 25, 2025 11:02 AM UTC

Hi Andreas Knoefel,


Thank you for sharing the details. We have reviewed your code and prepared a sample in the same way, but we were not able to clearly understand your issue. To clarify, we created a sample and observed the following: during load time, no appointments are present (representing no events) for November 25, 2025, and when the window is minimized, all date-range slots are rendered (for example, December–January 2026 when scrolling down, and October–November when scrolling up).

Please check and let us know if this matches the issue you are facing. If the problem is not reflected in the demo, kindly modify the shared sample to reproduce your issue so we can investigate further.


Regards,

Harsha.


Attachment: Load_time_Blank_issue_24094be3.zip


AK Andreas Knoefel November 26, 2025 04:32 AM UTC

The video looks exactly like what I am struggling with. What is the best way to fix this?

Maybe move the async data load in initialize() into a FutureBuilder? Any suggestions are appreciated.



HM Harsha Midadhala Khajareddy Midadhala Syncfusion Team November 26, 2025 02:30 PM UTC

Hi Andreas Knoefel,


We have ensured that the appointments are displayed at load time by default on Web platform without requiring the screen to be resized in the SfCalendar widget. We suspect that this might be a sample-level issue. In SfCalendar, the rendering logic is handled in two different layouts: Mobile and Desktop.

If SfCalendar is rendering on Android or iOS platforms, it uses the Mobile layout. Whereas for Windows, Web, MacOS, and Linux platforms, it uses the Desktop layout. Additionally, if the Calendar is rendered on a desktop platform and resized its screen to the mobile dimensions, then the Calendar widget will be switched to the Mobile layout. This is the current behavior of the SfCalendar widget.


Window:
1) With load time appointments

A screenshot of a computer

AI-generated content may be incorrect.

2) With zero appointments
A screenshot of a computer

AI-generated content may be incorrect.

Android:

1) With load time appointments
A screenshot of a calendar

AI-generated content may be incorrect.

2) With zero appointments

A screenshot of a phone

AI-generated content may be incorrect.



However, If appointments are still not displayed at load time on desktop platforms, we request you to replicate the mentioned behavior by modifying the attached sample. This will help us to assist you further.

If you have any further questions, feel free to reach out to us.


Regards,

Harsha.


Attachment: min_date_52180246.zip


AK Andreas Knoefel November 30, 2025 02:35 AM UTC

I managed to adapt your sample to the same behavior I observe with an async data source API call.

Note: Even though I moved the API call to the build section to avoid long initState calls, the behavior is consistent:

SfCalendar is called, but displays nothing until you interact with the screen / web page. 


Attachment: min_date_dc8b4326.zip


HM Harsha Midadhala Khajareddy Midadhala Syncfusion Team December 5, 2025 01:36 PM UTC

Hi Andreas Knoefe,

We were able to reproduce the reported issue in the provided sample. SfCalendar remains empty until there is user interaction when the asynchronous API call is triggered from the build method. This occurs because the first frame renders before the data is available, and the initial UI update isn’t triggered, causing the calendar to appear blank until a repaint happens after interaction.

To resolve this, we implemented the following changes:

  • Load data in initState instead of build to ensure the first render displays either a loader or the calendar.

  • Add if (!mounted) return, after any await to prevent calling setState on a disposed widget.

  • Always return a widget for loading, error, and success states to maintain a consistent UI experience.


void initState() {

    super.initState();

    _sfCalendarController = CalendarController();

    _loadData();

    final stream = Stream<int>.periodic(const Duration(milliseconds: 1500), (i) => i);

    _sub = stream.listen((event) {

      if (!mounted) return;

      setState(() => _streamValue = event);

    });

 

    _timer = Timer.periodic(const Duration(seconds: 1), (_) {

      if (!mounted) return;

      setState(() => _counter++);

    });

  }



We have attached the modified sample for your reference. These changes ensure that SfCalendar renders correctly on the first frame without requiring user interaction.


Regards,

Harsha.


Attachment: min_date_6810a4b7.zip

Marked as answer
Loader.
Up arrow icon