skip to Main Content

I created a simple calendar widget. I want to create a personal calendar for each user. For this purpose, I am using a ListView.builder.

Please find my code below

  @override
  Widget build(BuildContext context) {
    return new SizedBox(
        height: 1000,
        child: ListView.builder(
            shrinkWrap: true,
            scrollDirection: Axis.horizontal,
            itemCount: bookingList.length,
            itemBuilder: (context, index) {
              return Column(
                children: [
                  BookingCalendar(
                      bookingService: bookingCalendarModel,
                      convertStreamResultToDateTimeRanges:
                          convertStreamResultMock,
                      getBookingStream: getBookingStreamMock,
                      uploadBooking: uploadBookingMock,
                      pauseSlots: generatePauseSlots(),
                      hideBreakTime: false,
                      loadingWidget: const Text('Fetching data...'),
                      uploadingWidget: const CircularProgressIndicator(),
                      locale: 'en_US',
                      startingDayOfWeek: CalendarDays.monday,
                      wholeDayIsBookedWidget:
                          const Text('Fully booked! Choose another day'),
                      disabledDates: [DateTime(2023, 1, 20)],
                      disabledDays: [6, 7])
                ],
              );
            }));
  }

Everytime when i add the custom widget(BookingCalendar) inside the ListView i am getting a lot of errors:

No Material widget found.

Could you please tell my where is my mistake?

full code here:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:test_honours/model/doctors.dart';

import '../core/booking_calendar.dart';
import '../model/booking_service.dart';
import '../model/enums.dart';

void main() {
  initializeDateFormatting()
      .then((_) => runApp(const BookingCalendarDemoApp()));
}

class BookingCalendarDemoApp extends StatefulWidget {
  const BookingCalendarDemoApp({Key? key}) : super(key: key);

  @override
  State<BookingCalendarDemoApp> createState() => _BookingCalendarDemoAppState();
}

class _BookingCalendarDemoAppState extends State<BookingCalendarDemoApp> {
  final now = DateTime.now();
  late BookingModel bookingCalendarModel;
  List<BookingModel> bookingList = [];

  @override
  void initState() {
    super.initState();

    for (var i = 0; i < doctorsList.length; i++) {
      Doctor doctor = doctorsList[i];
      bookingList.add(bookingCalendarModel = new BookingModel(
          apptName: 'Mock Service',
          apptDuration: doctor.duration,
          bookingEnd: doctor.endHour,
          bookingStart: doctor.startHour));
    }
  }

  Stream<dynamic>? getBookingStreamMock(
      {required DateTime end, required DateTime start}) {
    return Stream.value([]);
  }

  Future<dynamic> uploadBookingMock({required BookingModel newBooking}) async {
    await Future.delayed(const Duration(seconds: 1));
    converted.add(DateTimeRange(
        start: newBooking.bookingStart, end: newBooking.bookingEnd));
    print('${newBooking.toJson()} has been uploaded');
  }

  List<DateTimeRange> converted = [];

  List<DateTimeRange> convertStreamResultMock({required dynamic streamResult}) {
    ///here you can parse the streamresult and convert to [List<DateTimeRange>]
    ///take care this is only mock, so if you add today as disabledDays it will still be visible on the first load
    ///disabledDays will properly work with real data
    DateTime first = now;
    DateTime tomorrow = now.add(Duration(days: 1));
    DateTime second = now.add(const Duration(minutes: 55));
    DateTime third = now.subtract(const Duration(minutes: 240));
    DateTime fourth = now.subtract(const Duration(minutes: 500));
    converted.add(
        DateTimeRange(start: first, end: now.add(const Duration(minutes: 30))));
    converted.add(DateTimeRange(
        start: second, end: second.add(const Duration(minutes: 23))));
    converted.add(DateTimeRange(
        start: third, end: third.add(const Duration(minutes: 15))));
    converted.add(DateTimeRange(
        start: fourth, end: fourth.add(const Duration(minutes: 50))));

    //book whole day example
    converted.add(DateTimeRange(
        start: DateTime(tomorrow.year, tomorrow.month, tomorrow.day, 5, 0),
        end: DateTime(tomorrow.year, tomorrow.month, tomorrow.day, 23, 0)));
    return converted;
  }

  List<DateTimeRange> generatePauseSlots() {
    return [
      DateTimeRange(
          start: DateTime(now.year, now.month, now.day, 12, 0),
          end: DateTime(now.year, now.month, now.day, 14, 0))
    ];
  }

  @override
  Widget build(BuildContext context) {
    return new SizedBox(
        height: 1000,
        child: ListView.builder(
            shrinkWrap: true,
            scrollDirection: Axis.horizontal,
            itemCount: bookingList.length,
            itemBuilder: (context, index) {
              return Column(
                children: [
                  BookingCalendar(
                      bookingService: bookingCalendarModel,
                      convertStreamResultToDateTimeRanges:
                          convertStreamResultMock,
                      getBookingStream: getBookingStreamMock,
                      uploadBooking: uploadBookingMock,
                      pauseSlots: generatePauseSlots(),
                      hideBreakTime: false,
                      loadingWidget: const Text('Fetching data...'),
                      uploadingWidget: const CircularProgressIndicator(),
                      locale: 'en_US',
                      startingDayOfWeek: CalendarDays.monday,
                      wholeDayIsBookedWidget:
                          const Text('Fully booked! Choose another day'),
                      disabledDates: [DateTime(2023, 1, 20)],
                      disabledDays: [6, 7])
                ],
              );
            }));
  }
}

2

Answers


  1. You are missing MaterialApp on main method

    void main() {
      initializeDateFormatting().then(
        (_) => runApp(
          MaterialApp(
            home: const BookingCalendarDemoApp(),
          ),
        ),
      );
    }
    
    Login or Signup to reply.
  2. This is because you can’t Define Root Widget:

    MaterialApp

    import 'package:flutter/cupertino.dart';
        import 'package:flutter/material.dart';
        import 'package:intl/date_symbol_data_local.dart';
        import 'package:test_honours/model/doctors.dart';
        
        import '../core/booking_calendar.dart';
        import '../model/booking_service.dart';
        import '../model/enums.dart';
        
        void main() {
          initializeDateFormatting()
              .then((_) => runApp(const MyApp()));
        }
        
        class MyApp extends StatelessWidget {
          const MyApp({super.key});
        
          // This widget is the root of your application.
          @override
          Widget build(BuildContext context) {
            return MaterialApp(
              debugShowCheckedModeBanner: false,
              title: 'Flutter Demo',
              theme: ThemeData(
                primarySwatch: Colors.blue,
              ),
              home:BookingCalendarDemoApp(),
            );
          }
        }
        
        class BookingCalendarDemoApp extends StatefulWidget {
          const BookingCalendarDemoApp({Key? key}) : super(key: key);
        
          @override
          State<BookingCalendarDemoApp> createState() => _BookingCalendarDemoAppState();
        }
        
        class _BookingCalendarDemoAppState extends State<BookingCalendarDemoApp> {
          final now = DateTime.now();
          late BookingModel bookingCalendarModel;
          List<BookingModel> bookingList = [];
        
          @override
          void initState() {
            super.initState();
        
            for (var i = 0; i < doctorsList.length; i++) {
              Doctor doctor = doctorsList[i];
              bookingList.add(bookingCalendarModel = new BookingModel(
                  apptName: 'Mock Service',
                  apptDuration: doctor.duration,
                  bookingEnd: doctor.endHour,
                  bookingStart: doctor.startHour));
            }
          }
        
          Stream<dynamic>? getBookingStreamMock(
              {required DateTime end, required DateTime start}) {
            return Stream.value([]);
          }
        
          Future<dynamic> uploadBookingMock({required BookingModel newBooking}) async {
            await Future.delayed(const Duration(seconds: 1));
            converted.add(DateTimeRange(
                start: newBooking.bookingStart, end: newBooking.bookingEnd));
            print('${newBooking.toJson()} has been uploaded');
          }
        
          List<DateTimeRange> converted = [];
        
          List<DateTimeRange> convertStreamResultMock({required dynamic streamResult}) {
            ///here you can parse the streamresult and convert to [List<DateTimeRange>]
            ///take care this is only mock, so if you add today as disabledDays it will still be visible on the first load
            ///disabledDays will properly work with real data
            DateTime first = now;
            DateTime tomorrow = now.add(Duration(days: 1));
            DateTime second = now.add(const Duration(minutes: 55));
            DateTime third = now.subtract(const Duration(minutes: 240));
            DateTime fourth = now.subtract(const Duration(minutes: 500));
            converted.add(
                DateTimeRange(start: first, end: now.add(const Duration(minutes: 30))));
            converted.add(DateTimeRange(
                start: second, end: second.add(const Duration(minutes: 23))));
            converted.add(DateTimeRange(
                start: third, end: third.add(const Duration(minutes: 15))));
            converted.add(DateTimeRange(
                start: fourth, end: fourth.add(const Duration(minutes: 50))));
        
            //book whole day example
            converted.add(DateTimeRange(
                start: DateTime(tomorrow.year, tomorrow.month, tomorrow.day, 5, 0),
                end: DateTime(tomorrow.year, tomorrow.month, tomorrow.day, 23, 0)));
            return converted;
          }
        
          List<DateTimeRange> generatePauseSlots() {
            return [
              DateTimeRange(
                  start: DateTime(now.year, now.month, now.day, 12, 0),
                  end: DateTime(now.year, now.month, now.day, 14, 0))
            ];
          }
        
          @override
          Widget build(BuildContext context) {
            return new SizedBox(
                height: 1000,
                child: ListView.builder(
                    shrinkWrap: true,
                    scrollDirection: Axis.horizontal,
                    itemCount: bookingList.length,
                    itemBuilder: (context, index) {
                      return Column(
                        children: [
                          BookingCalendar(
                              bookingService: bookingCalendarModel,
                              convertStreamResultToDateTimeRanges:
                              convertStreamResultMock,
                              getBookingStream: getBookingStreamMock,
                              uploadBooking: uploadBookingMock,
                              pauseSlots: generatePauseSlots(),
                              hideBreakTime: false,
                              loadingWidget: const Text('Fetching data...'),
                              uploadingWidget: const CircularProgressIndicator(),
                              locale: 'en_US',
                              startingDayOfWeek: CalendarDays.monday,
                              wholeDayIsBookedWidget:
                              const Text('Fully booked! Choose another day'),
                              disabledDates: [DateTime(2023, 1, 20)],
                              disabledDays: [6, 7])
                        ],
                      );
                    }));
          }
        }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search