类 'List<Event>' 在 Flutter 应用程序中没有实例 getter 'docs'

时间:2021-06-12 21:13:00

标签: flutter

我正在使用表格日历小部件构建约会安排页面。我可以将约会写入 firebase 集合/文档。现在,我需要从集合中提取约会并将它们显示为日历下方的列表。

我在另一个页面上使用了这段代码,我实际上是从那里复制的,并在这里使用它。该代码在另一页上有效,但我在这里收到错误消息。两页有细微差别,但差别不大。导致此错误的原因是什么?

这是日历页面的代码。

// Example holidays
final Map<DateTime, List> _holidays = {
  DateTime(2020, 1, 1): ['New Year\'s Day'],
  DateTime(2020, 1, 6): ['Epiphany'],
  DateTime(2020, 2, 14): ['Valentine\'s Day'],
  DateTime(2020, 4, 21): ['Easter Sunday'],
  DateTime(2020, 4, 22): ['Easter Monday'],
};

final eventsRef = FirebaseFirestore.instance.collection('agency').doc(globals.agencyId).collection('event');

bool showSpinner = false;

class AppointmentCalendarScreen extends StatefulWidget {
  AppointmentCalendarScreen({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _AppointmentCalendarScreenState createState() => _AppointmentCalendarScreenState();
}

class _AppointmentCalendarScreenState extends State<AppointmentCalendarScreen> with TickerProviderStateMixin {
  Map<DateTime, List> _events;
  List _selectedEvents;
  AnimationController _animationController;
  CalendarController _calendarController;
// =================================================================
  @override
  void initState() {
    super.initState();
    final _selectedDay = DateTime.now();

    _events = {
      _selectedDay.subtract(Duration(days: 30)): [
        'Event A0',
        'Event B0',
        'Event C0'
      ],
      _selectedDay.subtract(Duration(days: 27)): ['Event A1'],
      _selectedDay.subtract(Duration(days: 20)): [
        'Event A2',
        'Event B2',
        'Event C2',
        'Event D2'
      ],
      _selectedDay.subtract(Duration(days: 16)): ['Event A3', 'Event B3'],
      _selectedDay.subtract(Duration(days: 10)): [
        'Event A4',
        'Event B4',
        'Event C4'
      ],
      _selectedDay.subtract(Duration(days: 4)): [
        'Event A5',
        'Event B5',
        'Event C5'
      ],
      _selectedDay.subtract(Duration(days: 2)): ['Event A6', 'Event B6'],
      _selectedDay: ['Event A7', 'Event B7', 'Event C7', 'Event D7'],
      _selectedDay.add(Duration(days: 1)): [
        'Event A8',
        'Event B8',
        'Event C8',
        'Event D8'
      ],
      _selectedDay.add(Duration(days: 3)):
      Set.from(['Event A9', 'Event A9', 'Event B9']).toList(),
      _selectedDay.add(Duration(days: 7)): [
        'Event A10',
        'Event B10',
        'Event C10'
      ],
      _selectedDay.add(Duration(days: 11)): ['Event A11', 'Event B11'],
      _selectedDay.add(Duration(days: 17)): [
        'Event A12',
        'Event B12',
        'Event C12',
        'Event D12'
      ],
      _selectedDay.add(Duration(days: 22)): ['Event A13', 'Event B13'],
      _selectedDay.add(Duration(days: 26)): [
        'Event A14',
        'Event B14',
        'Event C14'
      ],
    };

    _calendarController = CalendarController();

    _animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 400),
    );

    _animationController.forward();
  }

  @override
  void dispose() {
    _animationController.dispose();
    _calendarController.dispose();
    super.dispose();
  }

  void _onDaySelected(DateTime day, List events, List holidays) {
    print('CALLBACK: _onDaySelected');
    setState(() {
      _selectedEvents = events;
    });
  }

  void _onVisibleDaysChanged(
      DateTime first, DateTime last, CalendarFormat format) {
    print('CALLBACK: _onVisibleDaysChanged');
  }

  void _onCalendarCreated(
      DateTime first, DateTime last, CalendarFormat format) {
    print('CALLBACK: _onCalendarCreated');
  }

  @override
  Widget build(BuildContext context) {
    final eventProvider = Provider.of<EventProvider>(context);

    return Scaffold(
      appBar: AppBar(
        automaticallyImplyLeading: false,
        title: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Image.asset('assets/images/Appbar_logo.png',
                fit: BoxFit.cover, height: 56),
          ],
        ),
      ),
      backgroundColor: Colors.white,
      resizeToAvoidBottomInset: false,
      body: Column(
        mainAxisSize: MainAxisSize.max,
        children: <Widget>[
          _buildTableCalendar(),

          const SizedBox(height: 8.0),
          ElevatedButton(
            onPressed: () async {
              setState(() {
                showSpinner = true;
              });
              try {
                globals.newAgency = true;

                Navigator.of(context).pushReplacement(MaterialPageRoute(
                    builder: (context) => AddEventScreen()));

                setState(() {
                  showSpinner = false;
                });
              } catch (e) {
                // todo: add better error handling
                print(e);
              }
            },
            child: Text('Add Event'),
          ),
          const SizedBox(height: 8.0),
          Expanded(child: _buildEventList()),
        ],
      ),
    );
  }

  // Simple TableCalendar configuration (using Styles)
  Widget _buildTableCalendar() {
    return TableCalendar(
      calendarController: _calendarController,
      events: _events,
      holidays: _holidays,
      startingDayOfWeek: StartingDayOfWeek.sunday,
      calendarStyle: CalendarStyle(
        selectedColor: Colors.deepOrange[400],
        todayColor: Colors.deepOrange[200],
        markersColor: Colors.deepPurpleAccent,
        outsideDaysVisible: false,
      ),
      headerStyle: HeaderStyle(
        formatButtonTextStyle:
        TextStyle().copyWith(color: Colors.white, fontSize: 15.0),
        formatButtonDecoration: BoxDecoration(
          color: Colors.deepOrange[400],
          borderRadius: BorderRadius.circular(16.0),
        ),
      ),
      onDaySelected: _onDaySelected,
      onVisibleDaysChanged: _onVisibleDaysChanged,
      onCalendarCreated: _onCalendarCreated,
    );
  }

  Widget _buildHolidaysMarker() {
    return Icon(
      Icons.add_box,
      size: 20.0,
      color: Colors.blueGrey[800],
    );
  }

  Widget _buildEventList() {
    return Container(
      child: StreamBuilder(
        stream: FirestoreService().getEvent(),
        builder: (context, snapshot) {
          if (!snapshot.hasData)
            return Center(
                child: const Text(
                  'Loading...',
                  style: TextStyle(
                      fontSize: 20, fontWeight: FontWeight.bold),
                ));
          return new ListView.builder(
              itemCount: snapshot.data.docs.length,
              itemBuilder: (BuildContext context, int index) {
                Event _event = Event.fromFirestore(
                    snapshot.data.docs[index].data());
                return ListTile(
                  isThreeLine: true,
                  title: Text(
                    'Event: ${_event.eventName ?? 'n/a'}',
                    style: TextStyle(
                        fontWeight: FontWeight.w900,
                        color: Colors.blueAccent),
                  ),
                  subtitle: Text.rich(TextSpan(
                      text:
                      '${_event.eventName ?? 'n/a'}, ${_event
                          .eventStartTime ?? 'n/a'}, ${_event
                          .eventDuration ?? 'n/a'}',
                      children: <TextSpan>[
                        TextSpan(
                          text:
                          '\n${_event.eventDescription ?? 'n/a'}',
                          style: TextStyle(
                              fontWeight: FontWeight.w900,
                              color: Colors.blueGrey),
                        )
                      ])),
                  onTap: () {
                    globals.newTrxn = false;
                    Navigator.of(context).push(MaterialPageRoute(
                        builder: (context) =>
                            AddEventScreen(
                                snapshot.data.docs[index])));
                  },
                );
    }
           
          );
        },

      ),
    );
  }
}

这是我得到的错误:

======== Exception caught by widgets library =======================================================
The following NoSuchMethodError was thrown building StreamBuilder<List<Event>>(dirty, state: _StreamBuilderBaseState<List<Event>, AsyncSnapshot<List<Event>>>#49aa8):
Class 'List<Event>' has no instance getter 'docs'.
Receiver: Instance(length:0) of '_GrowableList'
Tried calling: docs

这是提供者代码:

class EventProvider with ChangeNotifier {
  final firestoreService = FirestoreService();
  FirebaseFirestore _db = FirebaseFirestore.instance;
  //final eventRef = FirebaseFirestore.instance.collection(('events'));

  String _eventName;
  TimeOfDay _eventStartTime;
  String _eventDuration;
  DateTime _eventDate;
  String _eventDescription;
  String _agentId;
  String _agencyId;

  //Getters
  String get eventName => _eventName;
  TimeOfDay get eventStartTime => _eventStartTime;
  String get eventDuration => _eventDuration;
  DateTime get eventDate => _eventDate;
  String get eventDescription => _eventDescription;

  //Setters

  changeeventname(String value) {
    _eventName = value;
    notifyListeners();
  }

  changeeventstarttime(TimeOfDay value) {
    _eventStartTime = value;
    notifyListeners();
  }

  changeeventduration(String value) {
    _eventDuration = value;
    notifyListeners();
  }

  changeeventdate(DateTime value) {
    _eventDate = value;
    notifyListeners();
  }

  changeeventdescription(String value) {
    _eventDescription = value;
    notifyListeners();
  }

  loadValues(Event event) {
    _eventName = event.eventName;
    _eventStartTime = event.eventStartTime;
    _eventDuration = event.eventDuration;
    _eventDate = event.eventDate;
    _eventDescription = event.eventDescription;
  }

  saveEvent() {

    var newEvent = Event(
        eventName: _eventName,
        eventStartTime: _eventStartTime,
        eventDuration: _eventDuration,
        eventDate: _eventDate,
        eventDescription: _eventDescription,
        agencyId: globals.agencyId,
        agentId: globals.currentAgentId);


    // If the agency is a new agency retrieve the agency
    // document ID and save it to a new agent document
    if (globals.newEvent == true) {
      String id = _db.collection('event').doc().id;
      firestoreService.saveEvent(newEvent);
      globals.newEvent = false;
    } else {
      firestoreService.saveEvent(newEvent);
    }
  }
}

1 个答案:

答案 0 :(得分:1)

itemCountListView.builder 属性导致错误。

itemCount: snapshot.data.docs.length 应该是 itemCount: snapshot.data.length

这是因为Stream发出的数据类型是List<Event>。标准 List 类没有名为 docs 的方法,因此当 ListView.builder 尝试访问长度属性时,它会抛出 NoSuchMethodError

为列表中的任何项目调用 onTap 处理程序时会发生同样的错误,因为它也在引用 snapshot.data.docs