You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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的空安全机制:

  1. 非可空类型(Key、Color、double、int)的参数未指定默认值,也未添加required修饰符,导致隐式默认值null不符合类型要求。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 14:08:17