We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date
Unfortunately, activation email could not send to your email. Please try again.
Syncfusion Feedback

How to add custom header and view header in the Flutter Calendar

Platform: Flutter |
Control: SfCalendar

In the Flutter Event Calendar, you can customize the header and view header and it can be achieved by hiding headers and placing Container, Row, and Column widgets of the flutter.

STEP 1: Set the `HeaderHeight` and `ViewHeaderHeight` properties to `0` to hide the default headers. Please find the following image for the calendar without headers.

@override
Widget build(BuildContext context) {
  Expanded(
    child: SfCalendar(
      view: CalendarView.week,
      headerHeight: 0,
      viewHeaderHeight: 0,
    ),
  );
}

 

 

without headers

 

 

STEP 2: Add Container widget as a children for the header customization.

Container(
  color: Color(0xFF381460),
  width: width,
  height: 40,
  child: Text(_headerText!,
      textAlign: TextAlign.center,
      style: TextStyle(fontSize: 25, color: Colors.white)),
),

STEP 3: Add another Row widget as children for the `view header` customization of day.

Row(
  children: <Widget>[
    Container(
      color: Color(0xFFa278b5),
      width: cellWidth,
      child: Text(''),
    ),
    Container(
        color: Color(0xFFa278b5),
        width: cellWidth,
        child: Text(_viewHeaderText!, textAlign: TextAlign.center,
            style: TextStyle(color: Colors.white))),
    Container(
      color: Color(0xFFa278b5),
      width: cellWidth,
      child: Text(_viewHeaderText1!, textAlign: TextAlign.center, style: TextStyle(color: Colors.white)),
    ),
    Container(
      color: Color(0xFFa278b5),
      width: cellWidth,
      child: Text(_viewHeaderText2!, textAlign: TextAlign.center, style: TextStyle(color: Colors.white)),
    ),
    Container(
      color: Color(0xFFa278b5),
      width: cellWidth,
      child: Text(_viewHeaderText3!, textAlign: TextAlign.center, style: TextStyle(color: Colors.white)),
    ),
    Container(
      color: Color(0xFFa278b5),
      width: cellWidth,
      child: Text(_viewHeaderText4!, textAlign: TextAlign.center, style: TextStyle(color: Colors.white)),
    ),
    Container(
      color: Color(0xFFa278b5),
      width: cellWidth,
      child: Text(_viewHeaderText5!, textAlign: TextAlign.center,style: TextStyle(color: Colors.white)),
    ),
    Container(
      color: Color(0xFFa278b5),
      width: cellWidth,
      child: Text(_viewHeaderText6!, textAlign: TextAlign.center,style: TextStyle(color: Colors.white)),
    ),
  ],
),

STEP 4: Add Row widget as children for the view header customization of date.

Row(
  children: <Widget>[
    Container(
      color: Color(0xFFf6c3e5),
      width: cellWidth,
      height: 30,
      child: Text(""),
    ),
    Container(
      color: Color(0xFFf6c3e5),
      width: cellWidth,
      height: 30,
      child: Text(
        _dateText!,
        textAlign: TextAlign.center,
        style: TextStyle(fontSize: 25),
      ),
    ),
    Container(
      color: Color(0xFFf6c3e5),
      width: cellWidth,
      height: 30,
      child: Text(
        _dateText1!,
        textAlign: TextAlign.center,
        style: TextStyle(fontSize: 25),
      ),
    ),
    Container(
      color: Color(0xFFf6c3e5),
      width: cellWidth,
      height: 30,
      child: Text(
        _dateText2!,
        textAlign: TextAlign.center,
        style: TextStyle(fontSize: 25),
      ),
    ),
    Container(
      color: Color(0xFFf6c3e5),
      width: cellWidth,
      height: 30,
      child: Text(
        _dateText3!,
        textAlign: TextAlign.center,
        style: TextStyle(fontSize: 25),
      ),
    ),
    Container(
      color: Color(0xFFf6c3e5),
      width: cellWidth,
      height: 30,
      child: Text(
        _dateText4!,
        textAlign: TextAlign.center,
        style: TextStyle(fontSize: 25),
      ),
    ),
    Container(
      color: Color(0xFFf6c3e5),
      width: cellWidth,
      height: 30,
      child: Text(_dateText5!,
          textAlign: TextAlign.center,
          style: TextStyle(fontSize: 25)),
    ),
    Container(
      color: Color(0xFFf6c3e5),
      width: cellWidth,
      height: 30,
      child: Text(_dateText6!,
          textAlign: TextAlign.center,
          style: TextStyle(fontSize: 25)),
    ),
  ],
),

STEP 5: Then, add Expanded widget as children and place the calendar inside the Widget. Using the `OnViewChanged` event get the visible dates and using this you can assign the date values to the headers and view headers. 

Expanded(
    child: SfCalendar(
      headerHeight: 0,
      viewHeaderHeight: 0,
      controller: _controller,
      view: CalendarView.week,
      onViewChanged: (ViewChangedDetails viewChangedDetails) {
        if (_controller.view == CalendarView.week) {
          _headerText = DateFormat('MMMM yyyy')
              .format(viewChangedDetails
              .visibleDates[viewChangedDetails.visibleDates.length ~/ 2])
              .toString();
          _viewHeaderText = DateFormat('EEE')
              .format(viewChangedDetails.visibleDates[0])
              .toString();
          _viewHeaderText1 = DateFormat('EEE')
              .format(viewChangedDetails.visibleDates[1])
              .toString();
          _viewHeaderText2 = DateFormat('EEE')
              .format(viewChangedDetails.visibleDates[2])
              .toString();
          _viewHeaderText3 = DateFormat('EEE')
              .format(viewChangedDetails.visibleDates[3])
              .toString();
          _viewHeaderText4 = DateFormat('EEE')
              .format(viewChangedDetails.visibleDates[4])
              .toString();
          _viewHeaderText5 = DateFormat('EEE')
              .format(viewChangedDetails.visibleDates[5])
              .toString();
          _viewHeaderText6 = DateFormat('EEE')
              .format(viewChangedDetails.visibleDates[6])
              .toString();
          _dateText = DateFormat('dd')
              .format(viewChangedDetails.visibleDates[0])
              .toString();
          _dateText1 = DateFormat('dd')
              .format(viewChangedDetails.visibleDates[1])
              .toString();
          _dateText2 = DateFormat('dd')
              .format(viewChangedDetails.visibleDates[2])
              .toString();
          _dateText3 = DateFormat('dd')
              .format(viewChangedDetails.visibleDates[3])
              .toString();
          _dateText4 = DateFormat('dd')
              .format(viewChangedDetails.visibleDates[4])
              .toString();
          _dateText5 = DateFormat('dd')
              .format(viewChangedDetails.visibleDates[5])
              .toString();
          _dateText6 = DateFormat('dd')
              .format(viewChangedDetails.visibleDates[6])
              .toString();
        }
        if (viewChangedDetails.visibleDates[viewChangedDetails.visibleDates.length~/2].day % 2 == 0) {
          icon1 = Icon(
            Icons.wb_cloudy,
            color: Colors.grey,
          );
          icon2 = Icon(
            Icons.wb_sunny,
            color: Colors.amber,
          );
          icon3 = Icon(
            Icons.wb_incandescent,
            color: Color(0xFF0ba0000),
          );
          icon4 = Icon(
            Icons.wb_auto,
            color: Colors.orange,
          );
          icon5 = Icon(Icons.wb_iridescent, color: Color(0xFF0253e35));
          icon6 = Icon(
            Icons.wb_sunny,
            color: Colors.amber,
          );
          icon7 = Icon(
            Icons.wb_incandescent,
            color: Color(0xFF0ba0000),
          );
        } else if (viewChangedDetails.visibleDates[viewChangedDetails.visibleDates.length~/2].day % 5 == 0) {
          icon1 = Icon(
            Icons.wb_sunny,
            color: Colors.amber,
          );
          icon2 = Icon(
            Icons.wb_cloudy,
            color: Colors.grey,
          );
          icon3 = Icon(
            Icons.wb_sunny,
            color: Colors.amber,
          );
          icon4 = Icon(Icons.wb_iridescent, color: Color(0xFF0253e35));
          icon5 = Icon(
            Icons.wb_incandescent,
            color: Color(0xFF0ba0000),
          );
          icon6 = Icon(
            Icons.wb_auto,
            color: Colors.orange,
          );
          icon7 = Icon(
            Icons.wb_cloudy,
            color: Colors.grey,
          );
        } else if (viewChangedDetails.visibleDates[viewChangedDetails.visibleDates.length~/2].day % 4 == 0) {
          icon1 = Icon(
            Icons.wb_cloudy,
            color: Colors.grey,
          );
          icon2 = Icon(Icons.wb_incandescent);
          icon3 = Icon(
            Icons.wb_auto,
            color: Colors.orange,
          );
          icon4 = Icon(Icons.wb_iridescent, color: Color(0xFF0253e35));
          icon5 = Icon(
            Icons.wb_sunny,
            color: Colors.yellow,
          );
          icon6 = Icon(
            Icons.wb_cloudy,
            color: Colors.grey,
          );
          icon7 = Icon(
            Icons.wb_sunny,
            color: Colors.yellow,
          );
        } else if (viewChangedDetails.visibleDates[viewChangedDetails.visibleDates.length~/2].day % 3 == 0) {
          icon1 = Icon(
            Icons.wb_sunny,
            color: Colors.yellow,
          );
          icon2 = Icon(Icons.wb_iridescent, color: Color(0xFF0253e35));
          icon3 = Icon(
            Icons.wb_incandescent,
            color: Color(0xFF0ba0000),
          );
          icon4 = Icon(
            Icons.wb_sunny,
            color: Colors.amber,
          );
          icon5 = Icon(
            Icons.wb_auto,
            color: Colors.orange,
          );
          icon6 = Icon(
            Icons.wb_auto,
            color: Colors.orange,
          );
          icon7 = Icon(
            Icons.wb_cloudy,
            color: Colors.grey,
          );
        } else {
          icon1 = Icon(
            Icons.wb_sunny,
            color: Colors.amber,
          );
          icon2 = Icon(
            Icons.wb_iridescent,
            color: Color(0xFF0253e35),
          );
          icon3 = Icon(
            Icons.wb_sunny,
            color: Colors.amber,
          );
          icon4 = Icon(
            Icons.wb_cloudy,
            color: Colors.grey,
          );
          icon5 = Icon(Icons.wb_iridescent, color: Color(0xFF0253e35));
          icon6 = Icon(
            Icons.wb_incandescent,
            color: Color(0xFF0ba0000),
          );
          icon7 = Icon(
            Icons.wb_auto,
            color: Colors.orange,
          );
        }
        SchedulerBinding.instance!.addPostFrameCallback((duration) {
          setState(() {});
        });
      },
    )
),

 

Note:

addPostFrameCallback will be called after the widget build() is completed.

View sample in GitHub

 

Flutter calendar custom headers

 

 

ADD COMMENT
You must log in to leave a comment
Comments
Maria Donosova
Nov 01, 2021

Thank you for this tutorial, it's helpful. How can you display on your customer header the switch for view and arrows to switch between days/weeks/months?

Reply
Indumathi Ravichandran [Syncfusion]
Nov 01, 2021

Hi Maria,

Thank you for contacting Syncfusion support.

Regarding Query: How can you display on your customer header the switch for view and arrows to switch between days/weeks/months?

By using the forward() and backward() methods of the CalendarController, you can move to the previous and next days and using the view property of the CalendarController you can switch between calendar views with the help of PopupMenuButton and Icon buttons. We have UG and KB documentations for the same.

Please find the UG and KB documentations for the same.

UG link: https://help.syncfusion.com/flutter/calendar/date-navigations#programmatically-change-to-adjacent-dates

KB links: https://www.syncfusion.com/kb/12654/how-to-programmatically-navigate-to-the-adjacent-dates-in-the-flutter-calendar https://www.syncfusion.com/kb/12141/how-to-do-programmatic-navigation-using-flutter-calendar

Also, we have modified the sample for your requirement. Please find the sample from the following link.

Sample link: https://www.syncfusion.com/downloads/support/directtrac/general/ze/header-customization-calendar-flutter-master_(4)1541737144.zip

We hope that this helps you. Please let us know if you need further assistance.

Regards, Indumathi R

Reply
Maria Donosova
Nov 01, 2021

These controls are available for out of the box header. If I built a custom calendar header using the instruction above, how can I make visible forward() and backward() and an icon for view property?

Indumathi Ravichandran [Syncfusion]
Nov 02, 2021

Hi Maria,

Thank you for the update.

In the Flutter Calendar, by hiding the default header (headerHeight:0) you can design and add your own customer header with required elements, and we didn’t load any default calendar header elements in the custom header. For functionalities of those custom header elements kindly use the properties from the Flutter Calendar. Moving to the previous and next views, kindly use the forward() and backward() methods and use view property from CalendarController for switching between calendar views. So based on your requirement you can design the custom UI for the header.

We hope that this helps you. If possible, can you please share more details about your requirement clearly? It would be helpful for us to analyze and provide you with a solution at the earliest.

Regards, Indumathi R

Reply
M?nh Tu?n Nguy?n Van
Mar 07, 2023

This tutorial is very helpful for CalendarView.timelineWeek, but with CalendarView.timelineMonth, how to make the time header scroll along with calendar ?

Reply
Muniappan Subramanian [Syncfusion]
Mar 20, 2023

M?nh,

As of now, we do not have support for “Adding custom header in TimelineMonth view of the Flutter Calendar” and we have logged a feature request “Provide builder support for ViewHeader in the Flutter SfCalendar” for the same. We will implement this feature in any of our upcoming releases.  

At the planning stage for every release cycle, we review all open features and identify features for implementation based on specific parameters including product vision, technological feasibility, and customer interest. We will let you know when this feature is implemented. We appreciate your patience until then. 

Thank you for requesting this feature and helping us define it. We are always trying to make our products better and feature requests like yours are a key part of our product growth efforts. 
  
You can also communicate with us regarding the open features at any time using our Feature Report page.  

We will prioritize the features every release based on the demands and we do not have an immediate plan to implement this feature since we committed to already planned work. So, this feature will be available in any of our upcoming releases.  

Please upvote these features to make this our priority. While this feature itself is important we will prioritize the features every release, based on the user demands. So, this feature will be available in any of our upcoming releases 
  
Feedback link: https://www.syncfusion.com/feedback/42210/provide-builder-support-for-viewheader-in-the-flutter-sfcalendar

If you have any more specifications/suggestions for the feature request, you can add them as a comment in the portal and cast your vote to make it count. 

Please sign in to access our KB

This page will automatically be redirected to the sign-in page in 10 seconds.

Up arrow icon

Warning Icon You are using an outdated version of Internet Explorer that may not display all features of this and other websites. Upgrade to Internet Explorer 8 or newer for a better experience.Close Icon

Live Chat Icon For mobile