CircularProgressIndicator() not showing

279 Views Asked by At

The FormIncident() page takes about 2 seconds to load, but the CircularProgressIndicator() never show up.If I use a await Future.delayed(Duration(seconds: 2)); after the CircularProgressIndicator(), it does work.

I don't know what I'm doing wrong

  Future _MySpinner() async {
    showDialog(
        context: context,
        builder: (context) {
          return Center(
            child: CircularProgressIndicator(),
          );
        });

    await showDialog(context: context, builder: (context) => FormIncident());

    Navigator.of(context).pop();
  }

FormIncident()

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hive/hive.dart';
// import 'package:geocode/geocode.dart';
// import 'package:geocoding/geocoding.dart';
// import 'package:geolocator/geolocator.dart';
import 'package:intl/intl.dart';
import 'package:vortexcdl/model/incident_model.dart';
import '../list_states.dart';

enum WeatherOptions { Clear, Rain, Fog }

enum RoadwayOptions { Dry, Wet }

enum VisibilityOptions { Good, Poor }

String? weatherStatus = 'Clear';
String? roadwayStatus = 'Dry';
String? visibilityStatus = "Good";
String? address;
DateTime date = DateTime.now();
TimeOfDay time = TimeOfDay.now();
String? city;
String? state = null;
String? zip;
String? mileMarker;
String? contactName;
String? phone;
bool isReported = false;
String? policeReport;
String? descritpion;
bool isEditing = false;
Incident incident = Incident();
bool dateChange = false;
bool timeChange = false;
getIncident() {
  boxI.containsKey('0') ? {incident = boxI.get('0'), populateFields()} : null;
}

populateFields() {
  TimeOfDay stringToTimeOfDay(String tod) {
    final format = DateFormat.jm(); //"6:00 AM"
    return TimeOfDay.fromDateTime(format.parse(tod));
  }

  if (boxI.containsKey('0')) {
    !dateChange ? date = incident.date : null;
    !timeChange ? time = stringToTimeOfDay(incident.time!) : null;
    address = incident.address.toString();
    city = incident.city!.toString();
    zip = incident.zip!.toString();
    mileMarker = incident.mileMarker!.toString();
    contactName = incident.contact!.toString();
    phone = incident.contactPhoneNumber!.toString();
    isReported = incident.isReported;
    policeReport = incident.policeReport.toString();
    descritpion = incident.descritpion.toString();
    weatherStatus = incident.weatherStatus;
    roadwayStatus = incident.roadwayStatus;
    visibilityStatus = incident.visibilityStatus;
  }
}

late Box boxI;

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

  @override
  State<FormIncident> createState() => _FormIncidentState();
}

class _FormIncidentState extends State<FormIncident> {
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
  late FocusNode myFocusNode;

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

    myFocusNode = FocusNode();
  }

  @override
  void dispose() {
    // Clean up the focus node when the Form is disposed.
    myFocusNode.dispose();
    super.dispose();
  }

  Widget _builincidentAddress() {
    // address.text = incident.address.toString();
    return TextFormField(
      initialValue: address,
      decoration: InputDecoration(labelText: 'Address'),
      validator: (String? value) {
        if (value == null || value == '') {
          return 'Address is required';
        }
        return null;
      },
      onSaved: (String? value) {
        address = value!;
        incident.address = value;
      },
    );
  }

  Widget _builincidentCity() {
    isEditing ? city = incident.city.toString() : null;
    return TextFormField(
      initialValue: city,
      decoration: const InputDecoration(labelText: 'City'),
      validator: (String? value) {
        if (value == null || value == '') {
          return 'City is required';
        }
        return null;
      },
      onSaved: (String? value) {
        city = value!;
        incident.city = city!;
      },
    );
  }

  Widget _builincidentState() {
    boxI.containsKey('0') ? state = incident.state.toString() : null;
    return Container(
      margin: EdgeInsets.only(bottom: 2),
      child: DropdownButtonFormField<String>(
        value: state,
        isExpanded: true,
        decoration: InputDecoration(labelText: 'State'),
        hint: const Text('Select'),
        items: usStates
            .map((usState) => DropdownMenuItem<String>(
                  value: usState,
                  child: Text(usState, style: TextStyle(color: Colors.black)),
                ))
            .toList(),
        onChanged: (String? selecetedValue) {
          setState(() {
            state = selecetedValue!.toString();
            incident.state = selecetedValue.toString();
          });
        },
        validator: (value) => value == null ? 'Select a state' : null,
        onSaved: (String? value) {
          setState(() {
            state = value;
            incident.state = state;
          });
        },
      ),
    );
  }

  Widget _builincidentZip() {
    isEditing ? zip = incident.zip.toString() : null;
    return TextFormField(
      initialValue: zip,
      keyboardType: TextInputType.number,
      inputFormatters: [FilteringTextInputFormatter.digitsOnly],
      decoration: const InputDecoration(labelText: 'Zip'),
      validator: (String? value) {
        if (value == null || value == '') {
          return 'Zip is required';
        }
        return null;
      },
      onSaved: (String? value) {
        zip = value!;
        incident.zip = zip!;
      },
    );
  }

  Widget _builincidentMileMarker() {
    isEditing ? mileMarker = incident.mileMarker.toString() : null;
    return TextFormField(
      initialValue: mileMarker,
      keyboardType: TextInputType.number,
      inputFormatters: [FilteringTextInputFormatter.digitsOnly],
      decoration: const InputDecoration(labelText: 'Mile Marker'),
      onSaved: (String? value) {
        mileMarker = value!;
        incident.mileMarker = value;
      },
    );
  }

  Widget _builincidentContactPerson() {
    isEditing ? contactName = incident.contact.toString() : null;
    return TextFormField(
      initialValue: contactName,
      decoration: const InputDecoration(labelText: 'Contact Person'),
      validator: (String? value) {
        if (value == null || value == '') {
          return 'Contact Person is required';
        }
        return null;
      },
      onSaved: (String? value) {
        contactName = value!.toString();
        incident.contact = value;
      },
    );
  }

  Widget _builincidentContactPersonPhone() {
    isEditing ? phone = incident.contactPhoneNumber.toString() : null;
    return TextFormField(
      initialValue: phone,
      keyboardType: TextInputType.phone,
      inputFormatters: [FilteringTextInputFormatter.digitsOnly],
      decoration: const InputDecoration(labelText: 'Contact Phone'),
      validator: (String? value) {
        if (value == null || value == '') {
          return 'Contact Phone is required';
        }
        return null;
      },
      onSaved: (String? value) {
        phone = value.toString();
        incident.contactPhoneNumber = value;
      },
    );
  }

  Widget _buildPoliceReport() {
    isEditing ? policeReport = incident.policeReport.toString() : null;
    return Visibility(
      visible: isReported,
      child: TextFormField(
        initialValue: policeReport,
        decoration: const InputDecoration(labelText: 'Police report number'),
        validator: (String? value) {
          if (value == null || value == '') {
            return 'Police report is required';
          }
          return null;
        },
        onSaved: (String? value) {
          policeReport = value.toString();
          incident.policeReport = value;
        },
      ),
    );
  }

  Widget _buildIsReportedSwitch() {
    return SwitchListTile(
      title: const Text('Police Report'),
      value: isReported,
      onChanged: (bool value) {
        setState(() {
          isReported = value;
          incident.isReported = value;
        });
      },
      secondary: const Icon(
        Icons.local_police,
        color: Colors.teal,
      ),
    );
  }

  Widget _buildIncidentDescription() {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: TextFormField(
        focusNode: myFocusNode,
        initialValue: descritpion,
        minLines: 3,
        maxLines: 7,
        keyboardType: TextInputType.multiline,
        decoration: const InputDecoration(
            border: OutlineInputBorder(),
            labelText: 'Incident description in full detail'),
        validator: (String? value) {
          if (value == null || value == '') {
            return 'Incident Description is required';
          }
          return null;
        },
        onTap: () {
          myFocusNode.requestFocus();
        },
        onSaved: (String? value) {
          descritpion = value.toString();
          incident.descritpion = value;
        },
      ),
    );
  }

  Widget _buildincidentCard() {
    getIncident();
    // populateFields();
    return Scaffold(
      appBar: AppBar(title: Text('Incident Details')),
      body: SingleChildScrollView(
        physics: BouncingScrollPhysics(),
        child: Column(
          children: ([
            Form(
              key: _formKey,
              child: Card(
                elevation: 0,
                child: Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Column(
                    children: [
                      Row(
                        mainAxisAlignment: MainAxisAlignment.start,
                        children: [
                          Expanded(child: DateTimeDialog()),
                        ],
                      ),
                      // _buildGPS(),
                      Row(
                        children: [
                          Expanded(flex: 3, child: _builincidentAddress()),
                          Expanded(
                              flex: 2,
                              child: Padding(
                                padding: const EdgeInsets.only(left: 8.0),
                                child: _builincidentMileMarker(),
                              )),
                        ],
                      ),
                      Row(
                        children: [
                          Expanded(child: _builincidentCity()),
                          Expanded(
                              child: Padding(
                            padding: const EdgeInsets.fromLTRB(8, 0, 0, 3),
                            child: _builincidentState(),
                          )),
                          Expanded(
                              child: Padding(
                            padding: const EdgeInsets.fromLTRB(8.0, 0, 0, 0),
                            child: _builincidentZip(),
                          )),
                        ],
                      ),
                      Row(
                        children: [
                          Expanded(child: _builincidentContactPerson()),
                          Expanded(
                              child: Padding(
                            padding: const EdgeInsets.fromLTRB(8.0, 0, 0, 0),
                            child: _builincidentContactPersonPhone(),
                          )),
                        ],
                      ),
                      _buildIsReportedSwitch(),
                      _buildPoliceReport(),
                      RadioButtons(),
                      _buildIncidentDescription(),
                      Divider(),
                      _buildButtons(context),
                    ],
                  ),
                ),
              ),
            ),
          ]),
        ),
      ),
    );
  }

//#############################################################################################
  Widget _buildButtons(BuildContext context) => Padding(
        padding: const EdgeInsets.all(12.0),
        child: Row(mainAxisAlignment: MainAxisAlignment.end, children: [
          TextButton(
            child: Text('Cancel'),
            onPressed: () {
              // boxI.deleteFromDisk();
              Navigator.of(context).pop();
            },
          ),
          TextButton(
            child: Text('Save'),
            onPressed: () async {
              if (_formKey.currentState!.validate()) {
                _formKey.currentState!.save();
                await boxI.put('0', incident);
                Navigator.of(context).pop();
                dateChange = false;
                timeChange = false;
              }
            },
          ),
          TextButton(
            child: Text('Quick fill'),
            onPressed: () {
              Incident incident = Incident();
              incident.date = DateTime.parse('2021-01-27');
              incident.time = "06:30 AM";
              incident.address = '1070 Technology Dr';
              incident.mileMarker = '3';
              incident.city = 'Sarasota';
              incident.state = 'FL';
              incident.zip = '34231';
              incident.contact = 'PGT';
              incident.contactPhoneNumber = '645123987';
              incident.isReported = true;
              incident.policeReport = 'lakjsd';
              incident.weatherStatus = 'Rain';
              incident.roadwayStatus = 'Wet';
              incident.visibilityStatus = 'Poor';
              incident.descritpion =
                  'It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using \'Content here, content here\', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for \'lorem ipsum\' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).';
              boxI.put('0', incident);
              print('######################');
              print(boxI.get('0').date);
              print(boxI.get('0').time);
              print(boxI.get('0').address);
              print(boxI.get('0').mileMarker);
              print(boxI.get('0').city);
              print(boxI.get('0').state);
              print(boxI.get('0').zip);
              print('######################');
              dateChange = false;
              timeChange = false;

              Navigator.of(context).pop();
            },
          )
        ]),
      );

  @override
  Widget build(BuildContext context) {
    return _buildincidentCard();
  }
}

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

  @override
  State<RadioButtons> createState() => RadioButtonsState();
}

class RadioButtonsState extends State<RadioButtons> {
  Widget _buildWeatherStatusRadio() {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Expanded(
            child: Radio<String>(
                value: 'Clear',
                groupValue: weatherStatus,
                onChanged: (value) {
                  setState(() {
                    weatherStatus = value;
                    incident.weatherStatus = value!;
                  });
                })),
        Expanded(child: const Text('Clear')),
        Expanded(
            child: Radio<String>(
                value: 'Rain',
                groupValue: weatherStatus,
                onChanged: (value) {
                  setState(() {
                    weatherStatus = value;
                    incident.weatherStatus = value!;
                  });
                })),
        Expanded(flex: 1, child: const Text('Rain')),
        Expanded(
            child: Radio<String>(
                value: 'Fog',
                groupValue: weatherStatus,
                onChanged: (value) {
                  setState(() {
                    weatherStatus = value;
                    incident.weatherStatus = value!;
                  });
                })),
        Expanded(child: const Text('Fog')),
      ],
    );
  }

  Widget _buildRoadwayStatusRadio() {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Expanded(
            child: Radio<String>(
                value: 'Dry',
                groupValue: roadwayStatus,
                onChanged: (value) {
                  setState(() {
                    roadwayStatus = value;
                    incident.roadwayStatus = value!;
                  });
                })),
        Expanded(child: const Text('Dry')),
        Expanded(
            child: Radio<String>(
                value: "Wet",
                groupValue: roadwayStatus,
                onChanged: (value) {
                  setState(() {
                    roadwayStatus = value;
                    incident.roadwayStatus = value!;
                  });
                })),
        Expanded(flex: 1, child: const Text('Wet')),
      ],
    );
  }

  Widget _buildVisibilityStatusRadio() {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      mainAxisSize: MainAxisSize.min,
      children: [
        Expanded(
            child: Radio<String>(
                value: 'Good',
                groupValue: visibilityStatus,
                onChanged: (value) {
                  setState(() {
                    visibilityStatus = value;
                    incident.visibilityStatus = value!;
                  });
                })),
        Expanded(child: const Text('Good')),
        Expanded(
            child: Radio<String>(
                value: 'Poor',
                groupValue: visibilityStatus,
                onChanged: (value) {
                  setState(() {
                    visibilityStatus = value;
                    incident.visibilityStatus = value!;
                  });
                })),
        Expanded(child: const Text('Poor')),
      ],
    );
  }

  Widget build(BuildContext context) {
    return Column(children: [
      ListTile(
        // leading: Icon(
        //   Icons.wb_cloudy,
        //   color: Colors.teal,
        // ),
        title: Text('Weather'),
      ),
      Row(
        children: [
          Expanded(flex: 6, child: _buildWeatherStatusRadio()),
        ],
      ),
      ListTile(
        // leading: Icon(
        //   Icons.remove_road,
        //   color: Colors.teal,
        // ),
        title: Text('Roadway'),
      ),
      Row(
        children: [
          Expanded(flex: 4, child: _buildRoadwayStatusRadio()),
        ],
      ),
      ListTile(
        // leading: Icon(
        //   Icons.visibility,
        //   color: Colors.teal,
        // ),
        title: Text('Visibility'),
      ),
      Row(
        children: [
          Expanded(flex: 4, child: _buildVisibilityStatusRadio()),
        ],
      ),
    ]);
  }
}

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

  @override
  State<DateTimeDialog> createState() => _DateTimeDialogState();
}

class _DateTimeDialogState extends State<DateTimeDialog> {
  Widget _builincidentDate() {
    TextEditingController _date = TextEditingController();
    _date.text = DateFormat('MM-dd-yyyy').format(date);

    return ElevatedButton(
        onPressed: () async {
          await showDatePicker(
            context: context,
            initialDate: DateTime.now(),
            firstDate: DateTime(2000),
            lastDate: DateTime.now(),
          ).then((value) {
            setState(() {
              value != null ? date = value : null;
              incident.date = date;
              dateChange = true;
            });
            return date;
          });
        },
        child: Row(
          children: [
            Expanded(
                flex: 1,
                child: Icon(
                  Icons.today,
                  color: Colors.white,
                )),
            Expanded(
                flex: 3,
                child: Text(DateFormat('MM-dd-yyyy').format(incident.date))),
          ],
        ));
    // return TextFormField(
    //   decoration: const InputDecoration(labelText: 'Incident Date'),
    //   controller: _date,
    //   onTap: () async {
    //     date = await showDatePicker(
    //       context: context,
    //       initialDate: DateTime.now(),
    //       firstDate: DateTime(2000),
    //       lastDate: DateTime.now(),
    //     ).then((value) {
    //       setState(() {
    //         value != null ? date = value : null;
    //         incident.date = date;
    //         dateChange = true;
    //       });
    //       return date;
    //     });
    //   },
    // );
  }

  Widget _buidlincidentTime() {
    TextEditingController _time = TextEditingController();
    _time.text = time.format(context);
    return ElevatedButton(
      onPressed: () async {
        time = await showTimePicker(
          context: context,
          initialTime: TimeOfDay.now(),
        ).then((value) {
          setState(() {
            value != null ? time = value : null;
            incident.time = time.format(context);
            timeChange = true;
          });
          return time;
        });
      },
      child: Row(
        mainAxisAlignment: MainAxisAlignment.start,
        children: [
          Expanded(
              flex: 1,
              child: Icon(
                Icons.schedule,
                color: Colors.white,
              )),
          Expanded(flex: 3, child: Text(_time.text)),
        ],
      ),
    );
    // return TextFormField(
    //   decoration: const InputDecoration(labelText: 'Incident Time'),
    //   controller: _time,
    //   onTap: () async {
    //     time = await showTimePicker(
    //       context: context,
    //       initialTime: TimeOfDay.now(),
    //     ).then((value) {
    //       setState(() {
    //         value != null ? time = value : null;
    //         incident.time = time.format(context);
    //         timeChange = true;
    //       });
    //       return time;
    //     });
    //   },
    // );
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        ListTile(
          title: Text('Incident time'),
        ),
        Row(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            // Expanded(
            //     flex: 1,
            //     child: Icon(
            //       Icons.calendar_today,
            //       color: Colors.teal,
            //     )),
            Expanded(
                child: Padding(
              padding: const EdgeInsets.only(right: 4.0),
              child: _builincidentDate(),
            )),
            // Expanded(
            //     flex: 1,
            //     child: Icon(
            //       Icons.schedule,
            //       color: Colors.teal,
            //     )),
            Expanded(
                child: Padding(
              padding: const EdgeInsets.only(left: 4.0),
              child: _buidlincidentTime(),
            )),
          ],
        ),
      ],
    );
  }
}

1

There are 1 best solutions below

0
Gregory Conrad On

This is happening because you immediately push the new page to the router right after pushing your circular progress indicator. It would make more sense to have the FormIncident page have a loading icon until it has loaded, with something like FutureBuilder.