【问题标题】:How to display tasks that are not "checked" on the other screen?如何在另一个屏幕上显示未“选中”的任务?
【发布时间】:2021-09-21 16:40:09
【问题描述】:

我正在查看我的代码并想了 2 个小时,但没有运气,所以我会在这里寻求帮助。

我有一个按钮,当我按下它时,它会从列表视图中显示一个随机项目。问题是我在每个项目的列表视图上也有一个复选框。我不希望它(随机播放选中复选框的项目)只是随机播放列表视图中未选中/未选中/未完成的任务。

这是我的代码

class TaskData extends ChangeNotifier {
  List<Task> _tasks = [
    Task(name: "item1"),
    Task(name: "item2"),
    Task(name: "item3"),

  ];

  UnmodifiableListView<Task> get tasks {
    return UnmodifiableListView(_tasks);
  }

  int get taskCount {
    return _tasks.length;
  }
// <<Here is the code that shuffles through list
  Future<String> rann() async {
    return (_tasks.toList()..shuffle()).first.name;
  }
 
  void addTask(String newTaskTitle) {
    final task = Task(name: newTaskTitle);
    _tasks.add(task);
    notifyListeners();
  }

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

在另一个脚本中我有这个

class Task {
  final String name;
  bool isDone;

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

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

在另一个脚本文件中我有这段代码

        Padding(
          padding:
              const EdgeInsets.symmetric(horizontal: 20, vertical: 0),
          child: FutureBuilder(
            future: Provider.of<TaskData>(context).rann(),
            builder: (context, snapshot) {
              return Align(
                alignment: Alignment.center,
                child: Text(
                  "${snapshot.data}",
                  //softWrap: true,
                  textAlign: TextAlign.center,
                  //textWidthBasis: TextWidthBasis.longestLine,
                  style: TextStyle(
                      color: Colors.white,
                      fontSize: 30,
                      fontWeight: FontWeight.w700),
                ),
              );
            },
          ),
        ),

在另一个脚本中我有这个

class TasksList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Consumer<TaskData>(
      builder: (context, taskData, child) {
        return ListView.builder(
          itemBuilder: (context, index) {
            final task = taskData.tasks[index];
            return TaskTile(
              taskTitle: task.name,
              isChecked: task.isDone,
              checkboxCallback: (checkboxState) {
                taskData.updateTask(task);
              },
            );
          },
          itemCount: taskData.taskCount,
        );
      },
    );
  }
}

任何帮助将不胜感激!

编辑:我也忘了包含这部分代码

class TaskTile extends StatelessWidget {
  final bool isChecked;
  final String taskTitle;
  final Function(bool?) checkboxCallback;
  final VoidCallback longPressCallback;

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


  @override
  Widget build(BuildContext context) {
    return ListTile(
      onLongPress: longPressCallback,
      title: Text(
        taskTitle,
        // at the bottom, it sets decoration of text if isChecked is true, if its not its null
        style: TextStyle(
            decoration: isChecked ? TextDecoration.lineThrough : null),
      ),
      trailing: Checkbox(
        activeColor: Colors.blue,
        value: isChecked,
        onChanged: checkboxCallback,
      ),
    );
  }
}

【问题讨论】:

  • 您的描述太混乱了,请清除您的查询。首先,您说,“我不希望它显示(随机浏览选中复选框的项目)已经选中/选中的项目,我怎么可能这样做?”最后你说,“我不知道如何将这些连接起来,让它只在非检查列表中随机播放。”
  • 嗨,对不起,很混乱。我已尽力纠正并解释清楚,希望现在更好。

标签: list flutter dart random


【解决方案1】:

更新:

    class TaskData extends ChangeNotifier {
        List<Task> _undoneTasksShuffled = []

        // you don't need anymore the rann method() instead you should iterate over this listView           
        UnmodifiableListView<Task> get undoneTasksShuffled => UnmodifiableListView<Task>(_undoneTasksShuffled);

        @override
        void notifyListeners() {
            //this updates _undoneTasksShuffled every time you call notifyListeners
            _undoneTasksShuffled = _tasks.where((e)=> !e.isDone).toList()..shuffle();
            super.notifyListeners();
        }

        ...
    }

我认为您只需要在获取随机元素之前过滤结果。你需要修改你的 rann 方法,比如

//you don't really need a future method because you don't have async code
String rann() {
    final r = Random();
    final undoneTasks = _tasks.where((e)=> !e.isDone).toList();
    //this is for avoid RangeException on list. you can return any other thing
    if(undoneTasks.isEmpty) return '';
    // i think that you don't really need to shuffle whole list, you only need a random element
    return undoneTasks[r.nextInt(undoneTasks.length)].name;
}

我希望这能解决你的问题

【讨论】:

  • 您好,感谢您的帮助,它确实按我的意愿工作! --- random 和 shuffle 有什么区别? (我似乎有一个小问题,当我在 10 个项目中只有 3 个项目时,它只会选择 2 个,或者有时它会连续重复 3 次。有没有办法将它随机化,以便下次不会重复?所以下次随机化的时候不一样而是不一样。
  • 当我使用我拥有的随机播放代码时,它确实随机化得很好,当我使用 r.nextInt 时,当我有 3 个项目时,它只显示 2 个答案并忽略最后一个(我试过了大约 +20 次,从未显示过第 3 项)
  • 您好,关于您的第二个评论问题。我编辑了答案我有一个错字,因为 r.nextInt 方法需要一个 int 但它是独占的,所以你不需要将列表长度减 1
  • Random.nextInt() 和 List.shuffle 之间的区别在于 nextInt 返回一个介于 0 和给定整数之间的随机整数,并且基于该随机整数,您可以获得该列表中的随机元素,同时shuffle 方法改变列表中每个元素的顺序 什么是无效的,因为你只被带走了第一个元素
  • 感谢您的解释!使用随机而不是随机播放是有意义的。一个问题,你用 _undoneTasksShuffled 添加的 void NotifyListeners 和新类是什么?不知道用它做什么。我刚刚将 String rann() 更改为您更新的内容,并且它似乎在没有其他代码的情况下按我想要的方式工作?谢谢
猜你喜欢
  • 2023-04-02
  • 2021-07-29
  • 1970-01-01
  • 2012-06-03
  • 2021-01-28
  • 2022-10-05
  • 2020-02-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多