Flutter遇到的常见报错以及解决方案(持续更新)

 


一、报错

Non-nullable instance field 'username' must be initialized.

报错代码:

class _FormDemoState extends State<FormDemo> {
  final registerFormKey = GlobalKey<FormState>();
  String username, password; // 这行报错
  
  ...
}

解决方案参考:flutter2声明变量报错 Non-nullable instance field *** must be initialized._futter the non-nullable variable 'dperson' must be-CSDN博客

因 flutter2.0 添加了 Sound null safety 空安全声明,目的是通过显式声明可能为 null 的变量,增加 Dart 语言的鲁棒性。

因为 Dart 语言变量可以存 null 或者具体的值,因此在日常的开发中可能因为忘记赋值或者变量延迟赋值,导致访问某个变量时为 null,导致程序运行时抛出 exception。
这个功能推出后,可以从源码级解决 null 异常导致的错误。

有两种写法:

  • 在类型声明后添加 "?" 以标识这个变量是可以为 null 的。
  • 在类型声明前添加 "late" 以标识这个变量在使用前一定要进行初始化。

解决后的代码:

class _FormDemoState extends State<FormDemo> {
  final registerFormKey = GlobalKey<FormState>();
  late String username, password;
  
  ...
}

A value of type 'String?' can't be assigned to a variable of type 'String'.

报错代码:

TextFormField(
  decoration:
  InputDecoration(icon: Icon(Icons.people), labelText: "用户名或手机号"),
  onSaved: (value) {
    this.username = value; // 这行报错
  },
),

解决方案参考:dart - 不能将 'String?' 类型的值分配给 'String' 类型的变量flutter - 堆栈溢出 (stackoverflow.com)

在 Flutter 的最新更新中,他们强制要求为所有变量提供非 null 值。因此,如果你有机会在 DropdownButton 的 onChanged 回调中遇到 null 值,你将收到如下错误消息:“无法将 'String?' 类型的值分配给 'String' 类型的变量。

要解决此问题,您只需添加 !运算符添加到 value 变量中,如下所示:

TextFormField(
  decoration:
  InputDecoration(icon: Icon(Icons.people), labelText: "用户名或手机号"),
  onSaved: (value) {
    this.username = value!; // 这行报错
  },
),

The method 'save' can't be unconditionally invoked because the receiver can be 'null'.

报错代码:

void registerForm() {
  registerFormKey.currentState.save(); // 这行报错

  print("username:$username password:$password");
}

解决方案:'showBottomSheet' can't be unconditionally invoked because the receiver can be ' - 掘金 (juejin.cn)

解决办法:向目标中添加一个空检查('!')。

解决后的代码:

void registerForm() {
  registerFormKey.currentState!.save();

  print("username:$username password:$password");
}

Target of URI doesn't exist: 'package:fluttertoast/fluttertoast.dart'.

报错解释:

这个错误表明你的代码中引用了一个不存在的文件或库,具体是 'package:fluttertoast/fluttertoast.dart'。这通常发生在你尝试使用一个未正确添加到项目的依赖包。

解决方法:

  • 确认是否已经将 fluttertoast 添加到了你的项目依赖中。如果没有,你需要将它添加到你的 pubspec.yaml 文件的依赖中。

  • 打开 pubspec.yaml 文件,然后添加以下行:

dependencies:
  flutter:
    sdk: flutter
  fluttertoast: ^8.0.8

然后运行 flutter pub get 命令来安装新的依赖。

Target of URI doesn't exist: 'package:flutter/material.dart'.

解决方案:【Flutter】报错Target of URI doesn‘t exist ‘package:flutter/material.dart‘_target of uri doesn't exist-CSDN博客

解决办法:更新依赖库。

在 Flutter 目录下,执行 cmd 命令,执行以下指令:

flutter packages get

报错:

Flutter assets will be downloaded from https://storage.flutter-io.cn. Make sure you trust this source!
Launching lib\main.dart on Windows in debug mode...
windows/flutter/CMakeLists.txt does not use FLUTTER_TARGET_PLATFORM, updating.
Error: Building with plugins requires symlink support.

Please enable Developer Mode in your system settings. Run
  start ms-settings:developers
to open settings.

原因:这个错误表示你的系统尚未启用开发者模式,所以无法使用 Flutter 的插件功能。
Flutter 插件会通过符号链接的方式与 Flutter 工程连接,所以需要启用开发者模式和符号链接支持。

解决方案:Flutter报错Building with plugins requires symlink support的解决方法_building with plugins requires symlink support. pl-CSDN博客


Failed to download canvaskit

在命令行中输入:export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn

以使用国内镜像,如设置成功会出现:

Flutter assets will be downloaded from https://storage.flutter-io.cn. Make sure you trust this source!

Flutter : Could not find a generator for route RouteSettings

报错:

Could not find a generator for route RouteSettings("XXX", null) in the _WidgetsAppState.

原因:是一个工程中多次使用 MaterialApp ,也就是说,您应该只使用一个 MaterialApp 作为树的根。

解决:需要删除子页面中 MaterialApp,并将其改为 Scaffold。


The parameter 'key' can't have a value of 'null' because of its type, but the implicit default value is 'null'.

还有另一个类似的报错:The parameter 'title' can't have a value of 'null' because of its type, but the implicit default value is 'null'.

报错:

class HomePage extends StatefulWidget {
  const HomePage({Key? key, this.title}) : super(key: key);
  // ......
}

原因:demo 的 flutter 版本过老,新的 flutter 版本升级对相关调用类构造方法添加了空判断导致。

解决办法:The parameter 'title' can't have a value of 'null' because of its type 'String', but the implicit... - 简书

根据报错提示进行调整。可以用Key ?key来表示可空,又因为 title 是 final 修饰量,final 修饰的常量必须在声明进初始化或者在构造函数中初始化,它的值可以动态计算。 所以可以添加 required 修饰要求必须作为参数填入。

const HomePage({Key? key, required this.title}) : super(key: key);

不报错了,但是会有警告:Convert 'key' to a super parameter. (Documentation)

解决办法:Flutter关于构造函数的简化写法 - 简书,程序改为:

const HomePage({super.key,required this.title,});

二、警告

Use key in widget constructors.

警告代码:

class MyApp extends StatelessWidget { // MyApp这里警告
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: MyHomeBody(),
      ),
    );
  }
}

原因:在组件的构造函数中没有使用 key

解决后的代码:

class MyApp extends StatelessWidget {
  const MyApp({super.key}); // 使用key
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: MyHomeBody(),
      ),
    );
  }
}

Sort child properties last in widget instance creations.

警告代码:

class MyHomeBody extends StatelessWidget {
  const MyHomeBody({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Align(
      child: Icon(Icons.pets, size: 36, color: Colors.red), // 这行警告
      alignment: Alignment.bottomRight,
      widthFactor: 3,
      heightFactor: 3,
    );
  }
}

解决这个问题的方法是,在创建小部件时,确保子小部件作为最后一个参数传递,这样它们就会在属性列表的末尾。

解决后的代码:

class MyHomeBody extends StatelessWidget {
  const MyHomeBody({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Align(
      alignment: Alignment.bottomRight,
      widthFactor: 3,
      heightFactor: 3,      
      child: Icon(Icons.pets, size: 36, color: Colors.red), // child组件放到最后面
    );
  }
}

Avoid print` calls in production code.

警告代码:

class MyHomeBody extends StatelessWidget {
  ......

  print("结束滚动....");
  ......  
}

解决方案:

解决后的代码:

class MyHomeBody extends StatelessWidget {
  ......

  debugPrint("结束滚动....");
  ......  
}

Avoid using private types in public APIs.

警告代码:

class ScaffoldRoute extends StatefulWidget {
  const ScaffoldRoute({Key? key}) : super(key: key);
  @override
  _ScaffoldRouteState createState() => _ScaffoldRouteState(); // 这行报错
}

class _ScaffoldRouteState extends State<ScaffoldRoute> {
  ......
}

解决方案:

解决后的代码:

class ScaffoldRoute extends StatefulWidget {
  const ScaffoldRoute({Key? key}) : super(key: key);
  @override
  State<ScaffoldRoute> createState() => _ScaffoldRouteState();
}

class _ScaffoldRouteState extends State<ScaffoldRoute> {
  ......  
}

Prefer const literals as parameters of constructors on @immutable classes.

警告代码:

// 例子1
Expanded(
  child: ListView(
    children: <Widget>[ // 这行报警
      ListTile(
        leading: const Icon(Icons.add), // 这行报警
        title: const Text('Add account'), // 这行报警
      ),
      ListTile(
        leading: const Icon(Icons.settings), // 这行报警
        title: const Text('Manage accounts'), // 这行报警
      ),
    ],
  ),
),

// 例子2
bottomNavigationBar: BottomNavigationBar(
  // 底部导航
  items: <BottomNavigationBarItem>[  // 这行报警
    BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
    BottomNavigationBarItem(
      icon: Icon(Icons.business), label: 'Business'),
    BottomNavigationBarItem(icon: Icon(Icons.school), label: 'School'),
  ],
  currentIndex: _selectedIndex,
  fixedColor: Colors.blue,
  onTap: _onItemTapped,
),

解决方案:前面加上 const 就可以了

解决后的代码:

// 例子1
Expanded(
  child: ListView(
    children: const <Widget>[ // 这里加上const
      ListTile(
        leading: Icon(Icons.add),
        title: Text('Add account'),
      ),
      ListTile(
        leading: Icon(Icons.settings),
        title: Text('Manage accounts'),
      ),
    ],
  ),
),

// 例子2
bottomNavigationBar: BottomNavigationBar(
  // 底部导航
  items: const <BottomNavigationBarItem>[ // 这里加上const
    BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
    BottomNavigationBarItem(
      icon: Icon(Icons.business), label: 'Business'),
    BottomNavigationBarItem(icon: Icon(Icons.school), label: 'School'),
  ],
  currentIndex: _selectedIndex,
  fixedColor: Colors.blue,
  onTap: _onItemTapped,
),

This class (or a class that this class inherits from) is marked as '@immutable', but one or more of its instance fields aren't final:

警告代码:

class Login extends StatelessWidget {
  var userNameController = TextEditingController();
  var passWordController = TextEditingController();
  //......
}  

解决方案:为了解决这个警告,你可以在声明实例字段时将其标记为 final。参考:flutter开发警告This class (or a class that this class inherits from) is marked as ‘@immutable‘, but one_flutter this class (or a class that this class inh-CSDN博客

解决后的代码:

class Login extends StatelessWidget {
  final userNameController = TextEditingController();
  final passWordController = TextEditingController();
  //......
} 

Convert 'key' to a super parameter.

const MyApp({Key? key}) : super(key: key); // 这句警告

解决方案参考:Flutter关于构造函数的简化写法 - 简书 (jianshu.com)

改成下面这样就可以了:

const MyApp({super.key});
  • 在 Dart 2.17 版本后,新增了简化的构造函数参数传递方式,即可以使用 super.key 来直接将 key 传递给父类的构造函数,而不需要显式地定义 Key 参数。

Use 'const' with the constructor to improve performance.

解决方案:

Use 'const' with the constructor to improve performance.

This class (or a class that this class inherits from) is marked as '@immutable', but one or more of its instance fields aren't final

文件开头加上:

// ignore_for_file: must_be_immutable

参考:

Flutter 常见警告 - 简书 (jianshu.com)


posted @   fengMisaka  阅读(238)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示