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

qmelpv7a  于 2023-05-29  发布在  Flutter
关注(0)|答案(6)|浏览(133)

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

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)),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

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

String? newTaskTitle;

现在我得到了这个新的错误:错误:参数类型'String?“”不能分配给参数类型“String”。它指向这个方法:

void addTask(String newTaskTitle) {
    _tasks.add(Task(name: newTaskTitle));
    notifyListeners();
  }

我也把它修改成了这个:

void addTask(String? newTaskTitle) {
    _tasks.add(Task(name: newTaskTitle));
    notifyListeners();
  }

现在我得到了这个新的错误:错误:参数类型'String?“”不能分配给参数类型“String”。它指向这个代码:

class Task {
  final String name;
  bool isDone;

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

  void toggleDone() {
    isDone = !isDone;
  }
}

我也已经修复了它,这是变化:

class Task {
  final String? name;
  bool isDone;

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

  void toggleDone() {
    isDone = !isDone;
  }
}

现在这个错误再次出现:错误:参数类型'String?“”不能分配给参数类型“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();
                // });
              },
            );
          },
        );
      },
    );
  }
}

它指向这条线:

taskTitle: taskData.tasks[index].name,

这让我找到了这个文件

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,
      ),
    );
  }
}

这个文件想让我修改这个代码:

final String taskTitle;

这一个:

final String? taskTitle;

最后这段代码:

title: Text(
        taskTitle,
        style: TextStyle(
          decoration: isChecked ? TextDecoration.lineThrough : null,
        ),
      ),

这一个:

title: Text(
        taskTitle!,
        style: TextStyle(
          decoration: isChecked ? TextDecoration.lineThrough : null,
        ),
      ),

然后我hotrestared应用程序,并试图添加一个新的任务列表,但我得到这个错误:用于空值的空检查运算符,它指向以下代码的这一部分:

title: Text(
            taskTitle!,
            style: TextStyle(
              decoration: isChecked ? TextDecoration.lineThrough : null,
            ),
          ),

dart中的Null安全性真的很令人困惑..它会造成一个混乱的循环,让程序员无法平静地编写代码。请帮我解决这个问题…我真的很感激你提前。

liwlm1x9

liwlm1x91#

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

late String newTaskTitle;

这个错误是因为dart null安全,你不能指定null类型到非null字段。

dgsult0t

dgsult0t2#

而不是使用

String? newTaskTitle;

用这个

final newTaskTitle = TextEditingController();

并在TextField上将on更改为

controller:newTaskTitle,

然后在onPressed上更改为

onPressed: () {
                Provider.of<TaskData>(context, listen: false)
                    .addTask(newTaskTitle.text);
                Navigator.pop(context);
              },

这是在StatelessWidget中更改字符串的正确方法。

yqkkidmi

yqkkidmi3#

让它充满活力

dynamic newTaskTitle;

动态值可以处理null。在这个方法中,你可以这样做:

void addTask(dynamic newTaskTitle) {
    _tasks.add(Task(name: newTaskTitle));
    notifyListeners();
  }
mitkmikd

mitkmikd4#

只需添加一个空检查(!)在newtasktitle中,它将工作
就像我在这里添加的代码一样

onPressed: (){
  Provider.of<TaskData>(context, listen: false).addTask**(newTaskTitle!);**
  Navigator.pop(context);
},
bfrts1fy

bfrts1fy5#

你必须做两件事:
第一

Widget build(BuildContext context) {
String? newTaskTitle;

第二

onPressed: () {
                    Provider.of<TaskData>(context, listen: false)
                        .addTask(newTaskTitle!);
                    Navigator.pop(context);
                  },

请确保您添加listen:false作为nullcheck(!)将不够

2guxujil

2guxujil6#

1.i把我的AddTaskScreen变成statfulWidget。
2.然后我把newtaskname放在widget构建方法上面:String newTaskName;
3.i在textfield的onchange中添加了setState。
它工作,我不为什么

相关问题