Как элегантно использовать переменные для состояния в Flutter / Dart?

#android-studio #flutter #dart

#android-studio #flutter #dart

Вопрос:

 class EventCreator extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: <Widget> [
          Positioned.fill(
            child: Image(
              image: AssetImage('images/planning.jpg'),
              fit: BoxFit.cover,
            ),
          ),
          Container(
            child: Column(
              children: <Widget>[

                //DropdownBehavior(valueArg, listArg), idea

                DropdownBehavior(), // current

              ],
            ),
          ),
        ],
      ),
    );
  }
}

class DropdownBehavior extends StatefulWidget {
  DropdownBehavior({Key key}) : super(key: key);
  @override
  _DropdownBehavior createState() => _DropdownBehavior();
}

class _DropdownBehavior extends 
  State<DropdownBehavior> {
  String dropdownValue = "Public event";
  List<String> dropdownlist = ['Public event', ['Private event'];
                                         // These should be variables,
  @override                              // and be modifiable in EventCreator

  Widget build(BuildContext context) {
    return DropdownButton<String>(
      value: dropdownValue,
      elevation: 16,
      style: TextStyle(color: Colors.white),
      dropdownColor: Colors.black,
      underline: Container(
        height: 2,
        color: Colors.deepPurpleAccent,
      ),
      onChanged: (String newValue) {
        setState(() {
          dropdownValue = newValue;
        });
      },
      items: dropdownlist.map<DropdownMenuItem<String>>((String value) {
        return DropdownMenuItem<String>(
          value: value,
          child: Text(value),
        );
      }).toList(),
    );
  }

}
 

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

Я попробовал несколько различных реализаций конструктора в DropdownBehavior, но, похоже, мне не хватает знаний о состояниях в Flutter, потому что я не могу понять, как это работает. Я также не понимаю, как используется «Ключ» в конструкторе и как он используется.

Я использовал пример кода DropDownButton для общей реализации.

Я новичок в разработке Flutter и приложений, поэтому мне хотелось бы получить объяснение, почему то, что я делаю, глупо.

TL; DR: нужен общий класс, который я мог бы использовать для выпадающих меню, где я мог бы вводить значения начального значения подсказки и общий список значений на выбор.

Ответ №1:

Я мог бы рассмотреть то, что вы делаете, как объединение концепций управления состоянием и создания классов. Это может быть хорошо, или может быть лучше думать о них отдельно.

Например, я бы не подумал, что все, что вы написали здесь, слишком сильно связано с управлением состоянием, что касается того, что искать при поиске справки, а скорее просто создания виджетов. Отправной точкой для передачи переменных было бы помещение переменных в ваш класс DropDownBehavior (чтобы соответствовать ключу). Я думаю об этом проще: вместо создания виджета и состояния с отслеживанием состояния подумайте о том, чтобы просто попытаться создать функцию, которая принимает параметры и возвращает выпадающую кнопку.

Вот сокращенный пример:

 class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
  final String title;
//Etc.
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title)
         )
       );
   }
}


 

Комментарии:

1. Блестяще. Я попытался создать новый конструктор, но не понял, что мне все еще нужна его «ключевая» часть, и не понимал, что могу просто добавить дополнительные параметры после «ключевой» части. Теперь я должен быть в состоянии решить свою проблему.

Ответ №2:

 class DropdownBehavior extends StatefulWidget {
  DropdownBehavior({Key key, List<String> dropdownlist) : super(key: key); // added dropdownlist 
  final Function(String) selectedValue;
  @override
  _DropdownBehavior createState() => _DropdownBehavior();
}

class _DropdownBehavior extends 
  State<DropdownBehavior> {
  String dropdownValue = "Public event";
  List<String> dropdownlist = ['Public event', ['Private event']; 
                                         // These should be variables,
  @override                              // and be modifiable in EventCreator

  Widget build(BuildContext context) {
    return DropdownButton<String>(
      value: dropdownValue,
      elevation: 16,
      style: TextStyle(color: Colors.white),
      dropdownColor: Colors.black,
      underline: Container(
        height: 2,
        color: Colors.deepPurpleAccent,
      ),
      onChanged: (String newValue) {
        setState(() {
          widget.selectedValue(newValue); // added
          dropdownValue = newValue;
        });
      }, // added widget. below
      items: widget.dropdownlist.map<DropdownMenuItem<String>>((String value) {
        return DropdownMenuItem<String>(
          value: value,
          child: Text(value),
        );
      }).toList(),
    );
  }

}
 

Затем в вашем вызывающем классе введите
`DropdownBehavior(выпадающий список: mydropdownlist, выбранное значение: (Строка val) => setState(() => foo = val)

Волшебное ключевое слово для этого — функция обратного вызова

Комментарии:

1. Спасибо и вам за решение. Я выбрал другой ответ в качестве официального ответа, потому что в нем было больше глубины в общем объяснении. Тем не менее, спасибо за понимание того, как я могу лучше определить подобные проблемы в следующий раз, теперь я знаю, что нужно Google в следующий раз :).

2. С другой стороны, не могли бы вы уточнить последнюю строку /(String val) => setState(() => foo = val)/ ?

3. Это то, что вы найдете, если загуглите 😉 Вы вызываете DropdownBehaviour, с помощью которого будет отправлен обратный selectedValue вызов. Вы выбираете его значение с (Sting val) помощью и присваиваете его некоторой переменной состояния. Итак, foo = val — это то, что вы хотите сделать с выбранным значением

4. большое спасибо, в конце концов понял, как все применить. Многому научился из этой темы!