Передача данных между экранами, но с использованием извлеченного виджета раскрывающейся кнопки - PullRequest
0 голосов
/ 11 июля 2020

Прежде всего, вот мое состояние. Я пытаюсь передать все данные, которые были заполнены в раскрывающейся кнопке и средстве выбора даты и времени на первом экране (левое изображение), на второй экран (правое изображение). Проблема в том, что я извлек виджет DropDownButton в другой класс и не понимаю, как его реализовать.

First screen Второй экран

Перед этим это первый экран. Код:

  class InformationDetail extends StatefulWidget {
  static const String id = 'InformationDetail';
  @override
  _InformationDetailState createState() => _InformationDetailState();
}

class _InformationDetailState extends State<InformationDetail> {
  String addressText, addNotes;
  DateTime selectedDate = DateTime.now();
  TimeOfDay selectedTime = TimeOfDay.now();

  Future<Null> _selectDate(BuildContext context) async {
    final DateTime picked = await showDatePicker(
        context: context,
        initialDate: selectedDate,
        firstDate: DateTime(2015, 8),
        lastDate: DateTime(2101));
    if (picked != null && picked != selectedDate)
      setState(() {
        selectedDate = picked;
      });
  }

  Future<Null> _selectTime(BuildContext context) async {
    final TimeOfDay picked = await showTimePicker(
      context: context,
      initialTime: selectedTime,
    );
    if (picked != null && picked != selectedTime)
      setState(() {
        selectedTime = picked;
      });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
          child: ListView(
        children: <Widget>[
          Container(
            child: Column(
              children: <Widget>[
                Container(
                  margin: EdgeInsets.fromLTRB(25.0, 68.0, 70.0, 26.0),
                  child: Text(
                    'Information Detail',
                    style: TextStyle(fontSize: 35.0),
                  ),
                ),
                Column(
                  // Wrap Column
                  children: <Widget>[
                    Column(
                      children: <Widget>[
                        TitleName(
                          titleText: 'Grooming Type',
                          infoIcon: Icons.info,
                        ),
                        MenuDropDown(
                          dropdownText: 'Grooming Type...',
                          type: "groomingType",
                        ),
                        TitleName(
                          titleText: 'Cat Breeds',
                        ),
                        MenuDropDown(
                          dropdownText: 'Cat Breeds...',
                          type: "catBreeds",
                        ),
                        TitleName(
                          titleText: 'Cat Size',
                          infoIcon: Icons.info,
                        ),
                        MenuDropDown(
                          dropdownText: 'Cat Size...',
                          type: "catSize",
                        ),
                        TitleName(
                          titleText: 'Add-On Services',
                        ),
                        MenuDropDown(
                          dropdownText: 'Add - On Services...',
                          type: "addOnServices",
                        ),
                        TitleName(
                          titleText: 'Reservation Date',
                        ),
                        Row(
                          children: <Widget>[
                            Container(
                              width: 130,
                              height: 30,
                              margin: EdgeInsets.fromLTRB(50.0, 0, 62, 0),
                              child: RaisedButton(
                                color: Colors.white,
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(15.0),
                                ),
                                elevation: 6,
                                child: Text(
                                  'Choose Date',
                                  style: TextStyle(
                                    fontSize: 12.0,
                                  ),
                                ),
                                onPressed: () => _selectDate(context),
                              ),
                            ),
                            Text("${selectedDate.toLocal()}".split(' ')[0]),
                          ],
                        ),
                        TitleName(
                          titleText: 'Reservation Time',
                        ),
                        Row(
                          children: <Widget>[
                            Container(
                              width: 130,
                              height: 30,
                              margin: EdgeInsets.fromLTRB(50.0, 0, 62, 0),
                              decoration: BoxDecoration(),
                              child: RaisedButton(
                                color: Colors.white,
                                child: Text(
                                  'Choose Time',
                                  style: TextStyle(
                                    fontSize: 12.0,
                                  ),
                                ),
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(15.0),
                                ),
                                elevation: 6,
                                onPressed: () => _selectTime(context),
                              ),
                            ),
                            Text("${selectedTime.toString()}".split(' ')[0]),
                          ],
                        ),
                        TitleName(
                          titleText: 'Pick Up Address',
                        ),
                        Container(
                          width: 320,
                          height: 40,
                          child: TextFormField(
                            maxLines: null,
                            minLines: null,
                            expands: true,
                            decoration: InputDecoration(
                              contentPadding:
                                  EdgeInsets.fromLTRB(35.0, 10.0, 0, 10.0),
                              hintText: 'Address Here...',
                              hintStyle: TextStyle(
                                fontSize: 15.0,
                              ),
                              border: OutlineInputBorder(
                                borderRadius: BorderRadius.circular(15.0),
                              ),
                            ),
                            onChanged: (value) {
                              addressText = value;
                            },
                          ),
                        ),
                        TitleName(
                          titleText: 'Additional Notes',
                          infoIcon: Icons.info,
                        ),
                        Container(
                          width: 320,
                          child: TextFormField(
                            maxLines: 4,
                            decoration: InputDecoration(
                              contentPadding:
                                  EdgeInsets.fromLTRB(35.0, 10.0, 0, 10.0),
                              hintText: 'E.g. ',
                              hintStyle: TextStyle(
                                fontSize: 15.0,
                              ),
                              border: OutlineInputBorder(
                                borderRadius: BorderRadius.circular(15.0),
                              ),
                            ),
                            onChanged: (value) {
                              addNotes = value;
                            },
                          ),
                        ),
                        Container(
                          margin: EdgeInsets.fromLTRB(0, 15.0, 0, 0),
                          width: 75.0,
                          decoration: BoxDecoration(
                            color: Colors.white,
                            shape: BoxShape.rectangle,
                            border: Border.all(
                              color: Colors.black,
                            ),
                            borderRadius: BorderRadius.circular(12.0),
                          ),
                          child: IconButton(
                              icon: Icon(Icons.arrow_forward),
                              onPressed: () {
                                Navigator.of(context).push(MaterialPageRoute(
                                    builder: (context) => ConfirmationOrder(
                                          addressText: addressText,
                                          addNotes: addNotes,
                                        )));
                              }),
                        ),
                      ],
                    ),
                  ],
                ),
              ],
            ),
          ),
        ],
      )),
    );
  }
}

Под первым изображением есть кнопка для перехода ко второму экрану.

И вот класс, в котором я извлек DropDownButton:

    class MenuDropDown extends StatefulWidget {
  final String dropdownText;
  final String type;
  MenuDropDown({this.dropdownText, this.type});
  @override
  _MenuDropDownState createState() => _MenuDropDownState();
}

class _MenuDropDownState extends State<MenuDropDown> {
  String selectedItem;
  List<String> dropdownItems = [];

  List<String> groomingTypeList = ['Basic Grooming', 'Full Grooming'];

  List<String> catBreedsList = [
    'Persia',
    'Anggora',
    'Domestic',
    'Maine Coon',
    'Russian Blue',
    'Slamese',
    'Munchkin',
    'Ragdoll',
    'Scottish Fold',
  ];

  List<String> catSizeList = [
    'Small Size',
    'Medium Size',
    'Large Size',
    'Extra Large Size',
  ];

  List<String> addOnServicesList = [
    'Spa & Massage',
    'Shaving Hair / Styling',
    'Injection Vitamis Skin & Coat',
    'Cleaning Pet House and Environment',
    'Fur Tangled Treatment',
  ];

  List<String> getListBasedOnName(String value) {
    print(value);
    switch (value) {
      case "groomingType":
        return groomingTypeList;

        break;
      case "catBreeds":
        return catBreedsList;
        break;

      case "catSize":
        return catSizeList;
        break;
      case "addOnServices":
        return addOnServicesList;
        break;
    }

    return null;
  }

  @override
  void initState() {
    super.initState();
    print(widget.type);

    dropdownItems = getListBasedOnName(widget.type);
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.fromLTRB(0, 8.0, 0, 10.0),
      child: Container(
        width: 325.0,
        height: 50.0,
        decoration: BoxDecoration(
          boxShadow: [
            BoxShadow(
              color: Colors.black45,
              offset: Offset(2.5, 5.5),
              blurRadius: 5.0,
            )
          ],
          borderRadius: BorderRadius.circular(8),
          color: Colors.white,
        ),
        child: DropdownButtonHideUnderline(
          child: DropdownButton(
              value: selectedItem,
              hint: Padding(
                padding: const EdgeInsets.fromLTRB(22.0, 0, 0, 0),
                child: Text(
                  widget.dropdownText,
                  style: TextStyle(),
                ),
              ),
              items: dropdownItems.map((String value) {
                return new DropdownMenuItem<String>(
                  value: value,
                  child: new Text(value),
                );
              }).toList(),
              onChanged: (value) {
                setState(() {
                  selectedItem = value;
                });
              }),
        ),
      ),
    );
  }
}

Я действительно запутался, потому что функция onChanged в DropDownButton уже использовалась. Мне с трудом удается нормально передавать данные из текстового виджета. Но из раскрывающейся кнопки и средства выбора даты и времени я понятия не имею, как это сделать.

Есть ли способ получить данные с первого экрана, потому что на данный момент я еще не узнал о государственное управление или Blo c. А код все еще беспорядочный. Я еще не провел рефакторинг. Я очень надеюсь, что вы можете помочь с решением, спасибо!

1 Ответ

1 голос
/ 12 июля 2020

Во-первых, для MenuDropDown вы захотите сделать своего рода расширение для метода onChanged. Добавьте параметр VoidCallback в конструктор виджета, например:

typedef OnChangeCallback = void Function(dynamic value);

class MenuDropDown extends StatefulWidget {
  final String dropdownText;
  final String type;
  final OnChangeCallback onChanged;

  MenuDropDown({this.dropdownText, this.type, this.onChanged});

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

и в состоянии вызовите этот метод как часть собственного onChanged обратного вызова DropdownButton:

onChanged: (value) {
  setState(() {
    selectedItem = value;
  });
  widget.onChanged(value);
}

И в _InformationDetailState вы сохраните текущий выбранный элемент для каждого поля ввода и передадите функцию onChanged, которая обновляет соответствующее поле для каждого ввода:

String catSize; //Declare at the top of _InformationDetailState
...
MenuDropDown(
  dropdownText: 'Cat Size...',
  type: "catSize",
  onChanged: (value) {
    catSize = value;
  }
),

Теперь, чтобы передать данные на следующий экран. Никогда не бывает абсолютно необходимо использовать какое-либо управление состоянием в вашем приложении, и я обнаружил, что многие люди используют его без надобности. В вашем случае совершенно не обязательно просто передавать данные одному другому виджету. Вы уже правильно передаете addressText и addNotes. Просто расширите это значение для каждого параметра, который необходимо отображать на экране подтверждения. В качестве альтернативы вы можете сохранить все поля в одном Map вместо того, чтобы иметь переменную для каждого поля и передать это Map на страницу подтверждения.

...