Нет доступа к переменной в виджете Flutter Stateful Widget - PullRequest
0 голосов
/ 10 июля 2020

Я пытаюсь использовать переменную в классе с отслеживанием состояния в конструкторе, например, в DateTime. Но всегда получаю ошибку Only static members can be accessed in initializers.. Почему?

Часть кода

Здесь, в DateFormat, я не могу использовать переменную currentDate. Есть ли еще одна возможность получить доступ к этой переменной?

DateTime currentDate;

  final _form = GlobalKey<FormState>();
  final _dateTimeController = TextEditingController(
    text: DateFormat("HH:mm")
        .format(DateTime(currentDate.year, currentDate.month, currentDate.day,
            TimeOfDay.now().hour, TimeOfDay.now().minute))
        .toString(),
  );

  var _editedCalendarEntry = CalendarEntry(
      dateTime: DateTime.now(),
      meetingPlace: "",
      minutes: 0,
      servicePartner: "",
      status: "inactive",
      timestamp: Timestamp.now());

  @override
  void initState() {
    currentDate = widget.currentDate;
    super.initState();
  }

Весь класс

class AddCalendarEntry extends StatefulWidget {
  final ScrollController scrollController;
  final DateTime currentDate;

  AddCalendarEntry({this.scrollController, this.currentDate});

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

class _AddCalendarEntryState extends State<AddCalendarEntry> {
  DateTime currentDate;

  final _form = GlobalKey<FormState>();
  final _dateTimeController = TextEditingController(
    text: DateFormat("HH:mm")
        .format(DateTime(currentDate.year, currentDate.month, currentDate.day,
            TimeOfDay.now().hour, TimeOfDay.now().minute))
        .toString(),
  );

  var _editedCalendarEntry = CalendarEntry(
      dateTime: DateTime.now(),
      meetingPlace: "",
      minutes: 0,
      servicePartner: "",
      status: "inactive",
      timestamp: Timestamp.now());

  @override
  void initState() {
    currentDate = widget.currentDate;
    super.initState();
  }

  @override
  void dispose() {
    _dateTimeController.dispose();
    super.dispose();
  }

  Future<Null> _selectDate(BuildContext context) async {
    final DateTime picked = await showDatePicker(
      context: context,
      initialDate: widget.currentDate,
      firstDate: DateTime(2015, 8),
      lastDate: DateTime(2101),
    );
    if (picked != null && picked != currentDate)
      setState(() {
        currentDate = picked;
        print("Erfolgreich");
      });
    _editedCalendarEntry = CalendarEntry(
        servicePartner: _editedCalendarEntry.servicePartner,
        dateTime: DateTime(
            picked.year,
            picked.month,
            picked.day,
            _editedCalendarEntry.dateTime.hour,
            _editedCalendarEntry.dateTime.minute),
        meetingPlace: _editedCalendarEntry.meetingPlace,
        minutes: _editedCalendarEntry.minutes,
        status: _editedCalendarEntry.status);
  }

  void onTimeValueChanged(TimeOfDay time) {
    HapticFeedback.lightImpact();

    _editedCalendarEntry = CalendarEntry(
        servicePartner: _editedCalendarEntry.servicePartner,
        dateTime: DateTime(
            _editedCalendarEntry.dateTime.year,
            _editedCalendarEntry.dateTime.month,
            _editedCalendarEntry.dateTime.day,
            time.hour,
            time.minute),
        meetingPlace: _editedCalendarEntry.meetingPlace,
        minutes: _editedCalendarEntry.minutes,
        status: _editedCalendarEntry.status);

    setState(() {
      currentDate = _editedCalendarEntry.dateTime;
    });
  }

  Future<Null> _selectTime(BuildContext context) async {
    Navigator.of(context).push(
      showPicker(
          context: context,
          value: TimeOfDay(hour: 9, minute: 0),
          onChange: (time) => onTimeValueChanged(time),
          is24HrFormat: true,
          blurredBackground: false,
          accentColor: Theme.of(context).primaryColor),
    );
  }

  void _saveForm() {
    _form.currentState.save();
    print(_editedCalendarEntry.dateTime);
  }

  @override
  Widget build(BuildContext context) {
    return Material(
      color: Theme.of(context).bottomSheetTheme.backgroundColor,
      child: CupertinoPageScaffold(
        backgroundColor: Theme.of(context).bottomSheetTheme.backgroundColor,
        child: CustomScrollView(
          controller: widget.scrollController,
          physics: ClampingScrollPhysics(),
          slivers: <Widget>[
            CupertinoSliverNavigationBar(
                backgroundColor:
                    Theme.of(context).bottomSheetTheme.backgroundColor,
                automaticallyImplyLeading: false,
                largeTitle: Text("Neuer Eintrag"),
                border: Border.fromBorderSide(
                    BorderSide(color: Colors.transparent))),
            SliverToBoxAdapter(
              child: Padding(
                padding: const EdgeInsets.all(20.0),
                child: Container(
                  child: Form(
                      key: _form,
                      child: Column(
                        children: <Widget>[
                          Row(
                            children: <Widget>[
                              Container(width: 100, child: Text("Partner")),
                              Expanded(
                                child: TextFormField(
                                  strutStyle: StrutStyle.disabled,
                                  style: TextStyle(
                                      color: Theme.of(context).primaryColor),
                                  decoration: const InputDecoration(
                                      border: InputBorder.none),
                                  onSaved: (value) => {
                                    _editedCalendarEntry = CalendarEntry(
                                        servicePartner: value,
                                        dateTime: _editedCalendarEntry.dateTime,
                                        meetingPlace:
                                            _editedCalendarEntry.meetingPlace,
                                        minutes: _editedCalendarEntry.minutes,
                                        status: _editedCalendarEntry.status)
                                  },
                                ),
                              ),
                            ],
                          ),
                          Divider(
                            height: 0,
                          ),
                          Row(
                            children: <Widget>[
                              Container(width: 100, child: Text("Datum")),
                              Expanded(
                                child: TextFormField(
                                  initialValue: DateFormat('dd.MM.yyyy')
                                      .format(currentDate)
                                      .toString(),
                                  strutStyle: StrutStyle.disabled,
                                  readOnly: true,
                                  style: TextStyle(
                                      color: Theme.of(context).primaryColor),
                                  decoration: const InputDecoration(
                                    hintText: 'Datum',
                                    border: InputBorder.none,
                                  ),
                                ),
                              ),
                              CupertinoButton(
                                onPressed: () => _selectDate(context),
                                child: Text('Auswählen'),
                              ),
                            ],
                          ),
                          Divider(
                            height: 0,
                          ),
                          Row(
                            children: <Widget>[
                              Container(width: 100, child: Text("Uhrzeit")),
                              Expanded(
                                child: TextFormField(
                                  controller: _dateTimeController,
                                  strutStyle: StrutStyle.disabled,
                                  style: TextStyle(
                                      color: Theme.of(context).primaryColor),
                                  decoration: const InputDecoration(
                                      hintText: 'Uhrzeit',
                                      border: InputBorder.none),
                                ),
                              ),
                              CupertinoButton(
                                onPressed: () => _selectTime(context),
                                child: Text('Auswählen'),
                              ),
                            ],
                          ),
                          CupertinoButton.filled(
                              child: Text("Speichern"), onPressed: _saveForm)
                        ],
                      )),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

Спасибо за вашу помощь!

Ответы [ 2 ]

1 голос
/ 10 июля 2020
final _form = GlobalKey<FormState>();

// also TextEditingController data type should be initialized
// In your code, I cannot see that
final TextEditinController _dateTimeController = ...

... является инициализатором, и на данный момент нет возможности получить к нему доступ. Инициализаторы выполняются перед конструктором, но доступ к нему разрешен только после завершения вызова суперконструктора (неявного в вашем примере). Следовательно, доступ к нему разрешен только в теле конструктора (или более поздних версий).

Вот почему вы получаете сообщение об ошибке:

DateTime(currentDate.year, currentDate.month, currentDate.day, TimeOfDay.now().hour, TimeOfDay.now().minute)

обращается к _dateTimeController (это неявно, если вы не пишите это явно).

Что вы можете сделать, так это инициализировать свой _dateTimeController внутри initState(), после того, как ваш currentDate будет инициализирован

DateTime currentDate;

final _form = GlobalKey<FormState>();
final TextEditingController _dateTimeController;

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

  currentDate = widget.currentDate;

  // here you do that to prevent that error
  _dateTimeController = TextEditingController(
    text: DateFormat("HH:mm")
        .format(DateTime(currentDate.year, currentDate.month, currentDate.day,
            TimeOfDay.now().hour, TimeOfDay.now().minute))
        .toString(),
  );
}

Надеюсь, что ' Я рассею ваши сомнения и в большой степени помогу вам.

0 голосов
/ 10 июля 2020

Вы можете добавить это внутри initState. В классе у вас должно быть var _dateTimeController;˛

 _dateTimeController = TextEditingController(
    text: DateFormat("HH:mm")
        .format(DateTime(currentDate.year, currentDate.month, currentDate.day,
            TimeOfDay.now().hour, TimeOfDay.now().minute))
        .toString(),
  );
...