Flutter Cookbook第4章star.dart非空参数编译错误求助
Flutter Cookbook(第二版)第4章star.dart编译错误修复
我在阅读Simone Alessandria所著的《Flutter Cookbook(第二版)》时,第4章的star.dart文件出现多个编译错误,核心提示为参数不能为null,具体错误信息如下:
Launching lib/main.dart on Chrome in debug mode... lib/star.dart:8:9: Error: The parameter 'key' can't have a value of 'null' because of its type 'Key', but the implicit default value is 'null'. - 'Key' is from 'package:flutter/src/foundation/key.dart' ('../../../../SDK/flutter/packages/flutter/lib/src/foundation/key.dart'). Try adding either an explicit non-'null' default value or the 'required' modifier. Key key, ^^^ lib/star.dart:9:10: Error: The parameter 'color' can't have a value of 'null' because of its type 'Color', but the implicit default value is 'null'. - 'Color' is from 'dart:ui'. Try adding either an explicit non-'null' default value or the 'required' modifier. this.color, ^^^^^ lib/star.dart:10:10: Error: The parameter 'size' can't have a value of 'null' because of its type 'double', but the implicit default value is 'null'. Try adding either an explicit non-'null' default value or the 'required' modifier. this.size, ^^^^ lib/star.dart:65:9: Error: The parameter 'key' can't have a value of 'null' because of its type 'Key', but the implicit default value is 'null'. - 'Key' is from 'package:flutter/src/foundation/key.dart' ('../../../../SDK/flutter/packages/flutter/lib/src/foundation/key.dart'). Try adding either an explicit non-'null' default value or the 'required' modifier. Key key, ^^^ lib/star.dart:66:20: Error: The parameter 'value' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'. Try adding either an explicit non-'null' default value or the 'required' modifier. @required this.value, ^^^^^ Failed to compile application. Exited (1).
原star.dart代码如下:
import 'package:flutter/material.dart'; class Star extends StatelessWidget { final Color color; final double size; const Star({ Key key, this.color, this.size, }) : super(key: key); @override Widget build(BuildContext context) { return SizedBox( width: size, height: size, child: CustomPaint( painter: _StarPainter(color), ), ); } } class _StarPainter extends CustomPainter { final Color color; _StarPainter(this.color); @override void paint(Canvas canvas, Size size) { final paint = Paint()..color = color; final path = Path(); path.moveTo(size.width * 0.5, 0); path.lineTo(size.width * 0.618, size.height * 0.382); path.lineTo(size.width, size.height * 0.382); path.lineTo(size.width * 0.691, size.height * 0.618); path.lineTo(size.width * 0.809, size.height); path.lineTo(size.width * 0.5, size.height * 0.7639); path.lineTo(size.width * 0.191, size.height); path.lineTo(size.width * 0.309, size.height * 0.618); path.lineTo(size.width * 0.309, size.height * 0.618); path.lineTo(0, size.height * 0.382); path.lineTo(size.width * 0.382, size.height * 0.382); path.close(); canvas.drawPath(path, paint); } @override bool shouldRepaint(CustomPainter oldDelegate) { return false; } } class StarRating extends StatelessWidget { final Color color; final int value; final double starSize; const StarRating({ Key key, @required this.value, this.color = Colors.deepOrange, this.starSize = 25, }) : super(key: key); @override Widget build(BuildContext context) { return Row( children: List.generate( value, (_) => Padding( padding: const EdgeInsets.all(2.0), child: Star( color: color, size: starSize, ), ), ), ); } }
错误原因分析
这些错误源于Dart的空安全机制:
- 非可空类型(
Key、Color、double、int)的参数未指定默认值,也未添加required修饰符,导致隐式默认值null不符合类型要求。 StarRating中使用了旧版的@required注解,在Dart 2.12+空安全版本中已废弃,需替换为required关键字。
修复后的代码
import 'package:flutter/material.dart'; class Star extends StatelessWidget { final Color color; final double size; // 修复:Key改为可空类型Key?,给color和size添加默认值 const Star({ Key? key, this.color = Colors.deepOrange, this.size = 25, }) : super(key: key); @override Widget build(BuildContext context) { return SizedBox( width: size, height: size, child: CustomPaint( painter: _StarPainter(color), ), ); } } class _StarPainter extends CustomPainter { final Color color; _StarPainter(this.color); @override void paint(Canvas canvas, Size size) { final paint = Paint()..color = color; final path = Path(); path.moveTo(size.width * 0.5, 0); path.lineTo(size.width * 0.618, size.height * 0.382); path.lineTo(size.width, size.height * 0.382); path.lineTo(size.width * 0.691, size.height * 0.618); path.lineTo(size.width * 0.809, size.height); path.lineTo(size.width * 0.5, size.height * 0.7639); path.lineTo(size.width * 0.191, size.height); path.lineTo(size.width * 0.309, size.height * 0.618); path.lineTo(0, size.height * 0.382); path.lineTo(size.width * 0.382, size.height * 0.382); path.close(); canvas.drawPath(path, paint); } @override bool shouldRepaint(CustomPainter oldDelegate) { return false; } } class StarRating extends StatelessWidget { final Color color; final int value; final double starSize; // 修复:Key改为可空类型Key?,@required替换为required const StarRating({ Key? key, required this.value, this.color = Colors.deepOrange, this.starSize = 25, }) : super(key: key); @override Widget build(BuildContext context) { return Row( children: List.generate( value, (_) => Padding( padding: const EdgeInsets.all(2.0), child: Star( color: color, size: starSize, ), ), ), ); } }
关键修改点
Star构造函数:将Key key改为Key? key(允许key为空,符合Widget的常规用法),给color和size添加默认值,避免null问题。StarRating构造函数:将Key key改为Key? key,把@required替换为Dart空安全后的required关键字。- 移除了
_StarPainter中重复的路径绘制代码(原代码重复了path.lineTo(size.width * 0.309, size.height * 0.618);,已删除重复行)。
内容的提问来源于stack exchange,提问作者user3523406
相关产品推荐
相关产品推荐

