Передача функции в качестве параметра в flutter с нулевой безопасностью

#flutter #dart #dart-null-safety

#flutter #dart #dart-null-безопасность

Вопрос:

После обновления до Flutter 1.25.0-8.1.защита до нуля включена по умолчанию, и я начал изменять код своего проекта. Все работает нормально, за исключением функций, переданных в качестве параметров, как в следующем примере:

 class AppBarIcon extends StatelessWidget {
  final IconData icon;
  final Function onPressed;
  const AppBarIcon({Key? key, required this.icon, required this.onPressed}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return CupertinoButton(
      child: Icon(icon, size: 28, color: Colors.white),
      onPressed: onPressed,
    );
  }
}
 

onPressed является обязательным параметром, поэтому он не может быть нулевым, но, тем не менее, я получаю сообщение об ошибке при попытке передать функцию в CupertinoButton:

The argument type 'Function' can't be assigned to the parameter type 'void Function()?'.

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

Ответ №1:

Вы передаете Function() значение void Function() параметру, как он говорит. Измените свое объявление на final void Function() onPressed; так, чтобы ввод был более точным и не мог возвращать значение null или принимать аргументы.

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

1. Да, вам всегда нужно добавлять ключевое слово void раньше Function , даже если статический анализ dart не выдает ошибку.

Ответ №2:

Вы могли бы просто добавить скобку к объявлению функции следующим образом, Function() обновленный код приведен ниже.

 class AppBarIcon extends StatelessWidget {
  final IconData icon;
  final Function() onPressed;
  const AppBarIcon({Key? key, required this.icon, required this.onPressed}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return CupertinoButton(
      child: Icon(icon, size: 28, color: Colors.white),
      onPressed: onPressed,
    );
  }
}
 

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

1. В противном случае вы должны включить void Function() возврат dynamic .

2. @ИБРАГИМ АЛИ МУСА большое спасибо. вы сэкономили мое время.

Ответ №3:

Используйте VoidCallback вместо void Function() , и создайте свой собственный для тех, которые не определены.

 class FooWidget extends StatelessWidget {
  final VoidCallback onPressed; // Required
  final Widget Function(BuildContext context) builder; // Required 
  final VoidCallback? onLongPress; // Optional (nullable)

  FooWidget({
    required this.onPressed, 
    required this.builder, 
    this.onLongPress, 
  });

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onPressed,
      onLongPress: onLongPress,
      child: builder(context),
    );
  }
}