错误:必须先分配不可为 null 的局部变量“newTaskTitle”,然后才能使用它

del*_*ram 7 dart flutter

大家好,第一个错误在标题中,让我先展示代码:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:todoye_app_angela/models/task_data.dart';

class AddTaskScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    String newTaskTitle;
    return Container(
      color: Color(0xFF757575),
      child: Container(
        padding: EdgeInsets.all(20),
        decoration: BoxDecoration(
          color: Colors.limeAccent[400],
          borderRadius: BorderRadius.only(
            topLeft: Radius.circular(60),
            topRight: Radius.circular(60),
          ),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Text(
              'Add Task',
              textAlign: TextAlign.center,
              style: TextStyle(fontSize: 30, color: Colors.brown[900]),
            ),
            SizedBox(
              height: 12,
            ),
            TextField(
              onChanged: (newText) {
                newTaskTitle = newText;
              },
              autocorrect: false,
              decoration: InputDecoration(
                enabledBorder: OutlineInputBorder(
                  borderSide: BorderSide(
                    color: Colors.brown[800]!,
                    width: 2,
                  ),
                  borderRadius: BorderRadius.circular(30),
                ),
                hintText: 'Type Your Task ...',
                labelStyle: TextStyle(
                  color: Colors.green[900],
                ),
                helperStyle: TextStyle(
                  color: Colors.brown[900],
                ),
                focusedBorder: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(60),
                  borderSide: BorderSide(
                    color: Colors.brown[900]!,
                    width: 2,
                  ),
                ),
              ),
            ),
            SizedBox(
              height: 12,
            ),
            ElevatedButton(
              onPressed: () {
                Provider.of<TaskData>(context, listen: false)
                    .addTask(newTaskTitle);
                Navigator.pop(context);
              },
              child: Text(
                'Add',
                style: TextStyle(color: Colors.brown[900]),
              ),
              style: ButtonStyle(
                backgroundColor: MaterialStateColor.resolveWith(
                    (states) => Colors.lightGreen),
                elevation: MaterialStateProperty.resolveWith((states) => 6),
                shadowColor:
                    MaterialStateColor.resolveWith((states) => Colors.green),
                minimumSize: MaterialStateProperty.resolveWith(
                    (states) => Size.square(40.67)),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

错误出现在 onPress 提升按钮中,我试图将此值添加到“addTask”方法中...我已通过以下更改修复了此错误:

String? newTaskTitle;
Run Code Online (Sandbox Code Playgroud)

现在我收到这个新错误:错误:参数类型“字符串?” 无法分配给参数类型“String”。它指向这个方法:

void addTask(String newTaskTitle) {
    _tasks.add(Task(name: newTaskTitle));
    notifyListeners();
  }
Run Code Online (Sandbox Code Playgroud)

我也通过将其更改为这个来修复它:

void addTask(String? newTaskTitle) {
    _tasks.add(Task(name: newTaskTitle));
    notifyListeners();
  }
Run Code Online (Sandbox Code Playgroud)

现在我收到这个新错误:错误:参数类型“字符串?” 无法分配给参数类型“String”。它指向这段代码:

class Task {
  final String name;
  bool isDone;

  Task({
    required this.name,
    this.isDone = false,
  });

  void toggleDone() {
    isDone = !isDone;
  }
}
Run Code Online (Sandbox Code Playgroud)

我也修复了它,这是更改:

class Task {
  final String? name;
  bool isDone;

  Task({
    required this.name,
    this.isDone = false,
  });

  void toggleDone() {
    isDone = !isDone;
  }
}
Run Code Online (Sandbox Code Playgroud)

现在又出现这个错误:错误:参数类型“字符串?” 无法分配给参数类型“String”。看来这个错误很喜欢我!?...指向此代码{这是整个文件}:

class TaskList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // the consumer widget comes from the provider package we simply wrap it around the widget we want to listen to ....we have to specify the data type we want to have access to then...
    return Consumer<TaskData>(
      // then we provide the builder property which takes 3 arguments => 1: context : where we are in the widget tree ? second: it will provide the current data [Provider.of<TaskData>(context).task] and we can give that object a name ..here we named it taskData and at last it takes a property called child.
      builder: (context, taskData, child) {
        // here we return any widget that is needed to built based on this taskData .
        return ListView.builder(
          itemCount: taskData.taskCount,
          itemBuilder: (context, index) {
            return TaskTile(
              taskTitle: taskData.tasks[index].name,
              isChecked: taskData.tasks[index].isDone,
              checkboxCallback: (checkboxState) {
                // setState(() {
                //   Provider.of<TaskData>(context).tasks[index].toggleDone();
                // });
              },
            );
          },
        );
      },
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

它指向这一行:

taskTitle: taskData.tasks[index].name,
Run Code Online (Sandbox Code Playgroud)

这让我看到这个文件:

class TaskTile extends StatelessWidget {
  final String taskTitle;
  final bool isChecked;
  final ValueChanged<bool?> checkboxCallback;

  const TaskTile({
    required this.taskTitle,
    required this.isChecked,
    required this.checkboxCallback,
  });

  @override
  Widget build(BuildContext context) {
    return ListTile(
      title: Text(
        taskTitle,
        style: TextStyle(
          decoration: isChecked ? TextDecoration.lineThrough : null,
        ),
      ),
      trailing: Checkbox(
        activeColor: Colors.lime,
        value: isChecked,
        onChanged: checkboxCallback,
        // onChanged: toggleCheckBoxState,
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

该文件要求我更改此代码:

final String taskTitle;
Run Code Online (Sandbox Code Playgroud)

对于这个:

final String? taskTitle;
Run Code Online (Sandbox Code Playgroud)

最后这段代码:

title: Text(
        taskTitle,
        style: TextStyle(
          decoration: isChecked ? TextDecoration.lineThrough : null,
        ),
      ),
Run Code Online (Sandbox Code Playgroud)

对于这个:

title: Text(
        taskTitle!,
        style: TextStyle(
          decoration: isChecked ? TextDecoration.lineThrough : null,
        ),
      ),
Run Code Online (Sandbox Code Playgroud)

然后我重新启动了应用程序并尝试添加一个新任务到列表中,但我收到此错误:空检查运算符用于空值,它指向此代码的这一部分:

title: Text(
            taskTitle!,
            style: TextStyle(
              decoration: isChecked ? TextDecoration.lineThrough : null,
            ),
          ),
Run Code Online (Sandbox Code Playgroud)

dart 中的 Null Safety 确实令人困惑..它造成了一个混乱的循环,不允许程序员安静地编写代码....请帮我解决这个问题...我真的很感激。

小智 14

只需在 newTaskTitle 声明之前添加late 关键字即可。如下。

late String newTaskTitle;
Run Code Online (Sandbox Code Playgroud)

此错误是因为 dart null 安全性,您不能将 null 类型分配给不可为 null 的字段。