Flutter开发求助:map方法因接收者可能为null无法调用
Flutter Dart空安全报错:The method 'map' can't be unconditionally invoked because the receiver can be 'null'
跟随速通教程学习,在5分08秒处编写代码时遇到如下报错:
"The method 'map' can't be unconditionally invoked because the receiver can be 'null'"
我的代码如下:
import 'package:flutter/material.dart'; import 'dart:math'; class WaveColorPainter extends CustomPainter { Paint? _paint; List<Color>? colors; @override void paint(Canvas canvas, Size size) { colors = List.from(Colors.accents); colors!.removeRange(6, 13); //null safety List<Color> gradColors = colors.map( (color) => color.withOpacity( Random().nextDouble().clamp(0.5, 0.9), ), ); final Gradient gradient = LinearGradient(colors: gradColors); _paint = Paint() ..style = PaintingStyle.stroke ..strokeWidth = 1.5 ..shader = gradient.createShader( Rect.fromLTWH( 0, 20, size.width, 40, ), ); canvas.translate(0, size.height / 2); canvas.scale(1, -1); for (int i = 0; i < size.width.toInt(); i++) { double x = i.toDouble(); double r = 2 * sin(i) - 2 * cos(4 * i) + sin(2 * i - pi * 24); r = r * 5; canvas.drawLine(Offset(x, r), Offset(x, -r), _paint!); } // frequency bar } @override bool shouldRepaint(covariant CustomPainter oldDelegate) { return false; } }
已尝试在变量和函数上使用?和!操作符,但仍无法解决问题,VSCode报错截图如下:
解决方法
问题根源在于colors是可空成员变量(List<Color>?),即使你在paint方法里给它赋了值,Dart的空安全检查依然无法确定它在调用map时一定非空。同时还有一个隐藏问题:map返回的是Iterable<Color>,而LinearGradient的colors参数需要List<Color>,直接赋值会触发另一个报错。
推荐两种修复方式:
方式1:使用局部非空变量(更简洁安全)
把colors改成paint方法内的局部非空变量,彻底避免空安全问题:
@override void paint(Canvas canvas, Size size) { // 局部非空变量,无需处理空安全 final List<Color> colors = List.from(Colors.accents); colors.removeRange(6, 13); // map后转成List,适配LinearGradient要求 List<Color> gradColors = colors.map( (color) => color.withOpacity( Random().nextDouble().clamp(0.5, 0.9), ), ).toList(); final Gradient gradient = LinearGradient(colors: gradColors); _paint = Paint() ..style = PaintingStyle.stroke ..strokeWidth = 1.5 ..shader = gradient.createShader( Rect.fromLTWH(0, 20, size.width, 40), ); canvas.translate(0, size.height / 2); canvas.scale(1, -1); for (int i = 0; i < size.width.toInt(); i++) { double x = i.toDouble(); double r = 2 * sin(i) - 2 * cos(4 * i) + sin(2 * i - pi * 24); r = r * 5; canvas.drawLine(Offset(x, r), Offset(x, -r), _paint!); } }
方式2:给可空成员变量加非空断言
如果一定要保留成员变量,在调用map时明确添加非空断言!,同时补上toList():
List<Color> gradColors = colors!.map( (color) => color.withOpacity( Random().nextDouble().clamp(0.5, 0.9), ), ).toList();
内容的提问来源于stack exchange,提问作者loupdaniel
相关产品推荐
相关产品推荐

