Сделать параметр Function необязательным в флаттере пользовательского виджета

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

как сделать параметр типа Function необязательным в моем файле Widget.

class TextInputWithIcon extends StatefulWidget {
  final String iconPath;
  final String placeHolder;
  final Function(bool) onFocusChange;
  const TextInputWithIcon(
      {Key key,
      @required this.iconPath,
      this.placeHolder = "",
      this.onFocusChange})
      : super(key: key);

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

class _TextInputWithIconState extends State<TextInputWithIcon> {
@override
  Widget build(BuildContext context) {
    return MY_WIDGET;
   }
}

person Saman    schedule 30.01.2019    source источник
comment
Какая у вас ошибка? Это статично или во время выполнения?   -  person Günter Zöchbauer    schedule 30.01.2019
comment
@GünterZöchbauer. если функция не установлена ​​The method 'call' was called on null.   -  person Saman    schedule 30.01.2019
comment
Дело не в том, что параметр является необязательным, а в том, что когда этому параметру не передается никакая функция, тогда, конечно, вы не можете его вызвать. Не могли бы вы объяснить, каково ожидаемое поведение?   -  person Günter Zöchbauer    schedule 30.01.2019
comment
Я пытаюсь изменить фокус в «TextField» на родительском виджете. а просто в каком то экране изменение фокуса значения не имеет   -  person Saman    schedule 30.01.2019
comment
Как работает компонент, что это не имеет значения?   -  person Günter Zöchbauer    schedule 30.01.2019
comment
@GünterZöchbauer, спасибо за помощь. this.onFocusChange != null решить мою проблему   -  person Saman    schedule 30.01.2019
comment
Это или см. мой ответ.   -  person Günter Zöchbauer    schedule 30.01.2019


Ответы (4)


Необязательные параметры могут быть либо позиционными, либо именованными, но не обоими одновременно.

Именованные параметры являются необязательными по умолчанию, поэтому вам не нужно назначать значение по умолчанию.

Если параметр является необязательным, но не может быть нулевым, укажите значение по умолчанию< /а>.

С нулевой безопасностью

class TextInputWithIcon extends StatefulWidget {
  final String iconPath;
  final String placeHolder;
  final Function(bool)? onFocusChange; // nullable and optional
  
  const TextInputWithIcon(
      {Key? key,
      required this.iconPath, // non-nullable and required
      this.placeHolder = "", // non-nullable but optional with a default value
      this.onFocusChange, // nullable and optional
      })
      : super(key: key);

  @override
  _TextInputWithIconState createState() => _TextInputWithIconState();

}

Без нулевой безопасности

const TextInputWithIcon(
      {Key key,
      @required this.iconPath,
      this.placeHolder = "",
      this.onFocusChange
})
      : super(key: key);

Использование:

void _focusChanged(bool value) {

    // using null-aware operator (for both with and without null safety)
    onFocusChange?.call(value);
    
    // or without null-aware operator 
    
    // with null safety
    if(onFocusChange != null) {
      onFocusChange!(value);
    }

    // without null safety
    if(onFocusChange != null) {
      onFocusChange(value);
    }

  }

Взгляните на Необязательные параметры, чтобы лучше понять.

Редактировать: Спасибо, Джона Уильямс, за разъяснение.

person Umair M    schedule 30.01.2019
comment
onFocusChange не нужно инициализировать нулем. - person Jonah Williams; 30.01.2019
comment
Не требуется ли присвоение значения, чтобы сделать именованные параметры необязательными? - person Umair M; 30.01.2019
comment
Именованные параметры являются необязательными по умолчанию. - person Jonah Williams; 30.01.2019
comment
@UmairM нужно такое же решение для Null Safety. Пожалуйста, поделитесь любым предложением. Спасибо. - person Kamlesh; 16.05.2021
comment
@Kamlesh Я обновил ответ, пожалуйста, знайте, если я что-то пропустил :) - person Umair M; 25.05.2021
comment
this.placeHolder = , // не обнуляемый, но необязательный со значением по умолчанию помог мне. Спасибо Умайр. - person Kamlesh; 25.05.2021

Вы можете использовать значение по умолчанию, которое ничего не делает:

class TextInputWithIcon extends StatefulWidget {
  final String iconPath;
  final String placeHolder;
  final Function(bool) onFocusChange;
  const TextInputWithIcon(
      {Key key,
      @required this.iconPath,
      this.placeHolder = "",
      this.onFocusChange = _dummyOnFocusChange})
      : assert(onFocusChange != null), super(key: key);

  @override
  _TextInputWithIconState createState() => _TextInputWithIconState();

  static dynamic _dummyOnFocusChange(bool val) {}
}

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

Я добавил assert(...), чтобы убедиться, что ошибка отображается, когда null передается явно.

person Günter Zöchbauer    schedule 30.01.2019
comment
если моя функция не принимает аргумент и ничего не возвращает, это будет ›› (статический _dummyOnFocusChange() {}) таким образом правильный, потому что я пытался и выдавал ошибку во время компиляции, поэтому я пытался (статический динамический _dummyOnFocusChange() {} ) и работал со мной. Можете ли вы сказать мне, почему сработало ?? - person Magician; 08.04.2020
comment
Если вам нужно передать параметр, зависит от final Function(bool) onFocusChange. Если вы не собираетесь ничего возвращать, используйте void. dynamic - это своего рода подстановочный знак. - person Günter Zöchbauer; 08.04.2020
comment
для моего случая мне нужно передать пользовательскую модель. Я не могу просто объявить всю модель нулевой, мне нужна дополнительная информация о том, что ее там нет - person Dani; 13.02.2021
comment
@GünterZöchbauer, как мы можем передать необязательные параметры и использовать их в пользовательском виджете? Пожалуйста, предложите. Спасибо. - person Kamlesh; 16.05.2021

Другой вариант, если вам не нравятся именованные параметры (как я:/):

function_name (argument1, [argument2]) {
   // statements
}

аргументы в скобках необязательны.

источник

person Giorgos Kavalieratos    schedule 02.02.2021

Необязательный аргумент со значениями по умолчанию

Чтобы указать необязательный аргумент со значениями по умолчанию, мы используем {} фигурные скобки.

В необязательном позиционном аргументе и необязательном именованном аргументе, если мы не указываем значение в аргументе, оно устанавливается в NULL.

function_name (argument1, {argument2 = default_value}) {
  // statements
}

Синтаксис вызова функции

// if you want to override new value
function_name(argumentName : value); 

Образец

ShowMyDetails(String name,
 {String lastName = "Sanket", int age = 20}){
  print(name);
  print(lastName);
  print(age);
}

main() {
  ShowMyDetails("Jay", age: 24);
}
person Paresh Mangukiya    schedule 10.05.2021