如何为新 Screenroute 中的每个列表项提供自己的 Class 实例

How to provide own Class instance for each List item in new Screenroute

我想为 GroupData 中的每个组创建一个 TaskData 实例,并将其显示在新屏幕中,但我没有得到正确的方法。实际上,我在所有可用组中都有相同的任务列表。 任务功能运行良好。如果我点击复选标记,任务会被选中,但它会在所有可用组中发生。如何在每个组中获得一个新的任务列表?

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider<GroupData>(
          create: (context) => GroupData(),
        ),
        ChangeNotifierProvider<TaskData>(
          create: (context) => TaskData(),
        ),
      ],
      child: MaterialApp(
        theme: ThemeData.dark().copyWith(
//        scaffoldBackgroundColor: Color(0xFF3C3F40),
            ),
        home: GroupsScreen(),
      ),
    );
  }
}

class GroupsScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            IconButton(
              icon: Icon(
                FontAwesomeIcons.plusCircle,
                size: 30.0,
              ),
              onPressed: () {
                // Add group functionality
              },
            ),
            Expanded(
              child: Consumer<GroupData>(
                builder: (context, groupData, child) {
                  return ListView.builder(
                    itemBuilder: (context, index) {
                      final group = groupData.groups[index];
                      return GroupTile(
                        group: group,
                      );
                    },
                    itemCount: groupData.groupCount,
                  );
                },
              ),
            )
          ],
        ),
      ),
    );
  }
}

class GroupTile extends StatelessWidget {
  final Group group;

  GroupTile({
    @required this.group,
  });

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        Navigator.of(context).push(
          MaterialPageRoute(
            builder: (context) {
              return TasksScreen(
                group: group,
              );
            },
          ),
        );
      },
      child: Container(
        margin: EdgeInsets.all(10.0),
        child: Material(
          borderRadius: BorderRadius.circular(10.0),
          color: Color(0xFF626931),
          child: Container(
            padding: EdgeInsets.symmetric(
              horizontal: 10.0,
              vertical: 5.0,
            ),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Text(
                  group.title,
                  style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.w700),
                ),
                Row(
                  children: <Widget>[
                    Text(
                      '12 Tasks',
                      style: TextStyle(
                        fontSize: 10.0,
                        fontWeight: FontWeight.bold,
                        color: Colors.white70,
                      ),
                    ),
                  ],
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class TasksScreen extends StatelessWidget {
  final Group group;

  TasksScreen({this.group});
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider.value(
      value: group,
      child: Scaffold(
        body: SafeArea(
          child: Column(
            children: <Widget>[
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  IconButton(
                    icon: Icon(
                      FontAwesomeIcons.angleLeft,
                      size: 30.0,
                    ),
                    onPressed: () {
                      Navigator.pop(context);
                    },
                  ),
                  Text(
                    group.title,
                    style: TextStyle(
                      fontSize: 30.0,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  IconButton(
                    icon: Icon(
                      FontAwesomeIcons.plusCircle,
                      size: 30.0,
                    ),
                    onPressed: () {
                      // add task to group functionality
                    },
                  ),
                ],
              ),
              Expanded(
                child: Consumer<TaskData>(
                  builder: (context, taskData, child) {
                    print(taskData);
                    return ListView.builder(
                      itemBuilder: (context, index) {
                        final task = taskData.tasks[index];
                        return TaskTile(
                          name: task.name,
                          isChecked: task.isDone,
                          onLongPressCallback: () {
                            taskData.deleteTask(task);
                          },
                          checkboxCallback: (checkboxState) {
                            taskData.updateTask(task);
                          },
                        );
                      },
                      itemCount: taskData.taskCount,
                    );
                  },
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class TaskTile extends StatelessWidget {
  final bool isChecked;
  final String name;
  final Function checkboxCallback;
  final Function onLongPressCallback;

  TaskTile(
      {this.name,
      this.isChecked,
      this.checkboxCallback,
      this.onLongPressCallback});

  @override
  Widget build(BuildContext context) {
    return ListTile(
      onLongPress: onLongPressCallback,
      title: Text(
        name,
        style: TextStyle(
          decoration: isChecked ? TextDecoration.lineThrough : null,
        ),
      ),
      trailing: Checkbox(
        value: isChecked,
        onChanged: checkboxCallback,
      ),
    );
  }
}
class GroupData extends ChangeNotifier {
  List<Group> _groups = [
    Group(
      title: 'Group 1',
    ),
    Group(
      title: 'Group 2',
    ),
  ];

  get groups {
    return _groups;
  }

  void updateGroupData() {
    notifyListeners();
  }

  void addGroup(Group group) {
    _groups.add(group);
    notifyListeners();
  }

  get groupCount {
    return groups.length;
  }
}
class TaskData extends ChangeNotifier {
  List<Task> _tasks = [
    Task(name: 'Buy milk'),
    Task(name: 'watch a movie'),
    Task(name: 'have a coffee'),
  ];

  get tasks {
    return _tasks;
  }

  int get taskCount {
    return _tasks.length;
  }

  void addTask(Task newTask) {
    _tasks.add(newTask);
    notifyListeners();
  }

  void updateTask(Task task) {
    task.toggleIsDone();
    notifyListeners();
  }

  void deleteTask(Task task) {
    _tasks.remove(task);
    notifyListeners();
  }
}
class Group extends ChangeNotifier {
  String title;
  TaskData taskData;

  Group({this.taskData, this.title});
}
class Task {
  String name;
  bool isDone;

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

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

根据我从您的代码中看到的情况,您正在将数据从 taskData 变量传递到 task 变量,然后调用您的 TaskTile.

为了处理每个单独的状态,您需要更新数组列表中的值,即 taskData 变量,

尝试将 taskData.task[index] 直接传递给您的 `TaskTile,然后它将处理单独的状态

ListView.builder(
      itemBuilder: (context, index) {
        return TaskTile(
             name: taskData.tasks[index].name,
             isChecked: taskData.tasks[index].isDone,
             onLongPressCallback: () {
                 taskData.deleteTask(taskData.tasks[index]);
             },
             checkboxCallback: (checkboxState) {
               taskData.updateTask(taskData.tasks[index]);
             },
          );
         ,
       itemCount: taskData.taskCount,
   );

GroupTile

也一样

感谢@Vicky Salunkhe 的回答,但你提到的内容已经存在。

经过 2 天的头脑风暴后,我找到了解决方案。

而不是这个:

class GroupTile extends StatelessWidget {
  final Group group;

  GroupTile({
    @required this.group,
  });

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        Navigator.of(context).push(
          MaterialPageRoute(
            builder: (context) {
              return TasksScreen(
                group: group,
              );
            },
          ),
        );
      },
    );
  }
}

有效的解决方案是这样的: 使用 final TaskData taskData = TaskData(); 创建一个新的 TaskData 实例 并使用这个新的 TaskData 实例创建一个具有现有实例的提供者:

ChangeNotifierProvider.value(
  value: taskData,
  child: TasksScreen(
    group: group,
  ),
);

完整代码示例:

class GroupTile extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final group = Provider.of<Group>(context);
    final TaskData taskData = TaskData();
    return GestureDetector(
      onTap: () {
        Navigator.of(context).push(
          MaterialPageRoute(
            builder: (context) {
              return ChangeNotifierProvider.value(
                value: taskData,
                child: TasksScreen(
                  group: group,
                ),
              );
            },
          ),
        );
      },
    );
  }
}