Как мне поместить ReorderableListView в Sliver?

Мне нужен SliverAppBar в верхней части экрана и SliverFillRemaining под ReorderableListView.

Я пробовал несколько решений и каждый раз получаю разные ошибки. CustomSCrollView с ReorderableListView, помещенным внутри свойства slovers, выдает ошибку "Неудачное утверждение: строка 4345, позиция 14: 'owner._debugCurrentBuildTarget == this': неверно".

Я также попытался добавить SliverChildListDelegate и поместить внутрь него ReorderableListView, что дает еще одну ошибку.

2 ответа

Я считаю, что именно поэтому существует пакет reorderables - я не думаю, что ReorderableListView поддерживает осколки из коробки, поэтому кто-то сделал версию, которая поддерживает. Он не ведет себя точно так же, и есть некоторые ограничения (например, вы не можете настроить, какая область виджета или какой жест является триггером для перетаскивания - вы можете только долго нажимать на весь виджет), но мне кажется, это работает.

Показывает черный экран - см. Комментарий. Также выдает ошибку: Во время выполнения функции performResize() было выдано следующее утверждение: объекту _RenderTheatre был задан бесконечный размер во время макета.

А также эта ошибка: BoxConstraints устанавливает бесконечную высоту.

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(slivers: [
        SliverToBoxAdapter(
          child: ReorderableListView(
            onReorder: (oldIndex, newIndex) {
              setState(() {
                if (newIndex > oldIndex) {
                  newIndex -= 1;
                }
                final Todo item = TodoList.myTodos.removeAt(oldIndex);
                TodoList.myTodos.insert(newIndex, item);
              });
            },
            children: [
              for (final todo in TodoList.myTodos)
                Dismissible(
                  onDismissed: (direction) {
                    if (direction == DismissDirection.startToEnd && todo.done == false) {
                      // Mark todo as done
                      todo.done = true;
                      TodoList.myTodos.add(Todo(todo.title, todo.done = true,
                          todo.oldIndex = TodoList.myTodos.indexOf(todo)));
                      TodoList.myTodos.remove(todo);
                      debugPrint("Todo ${todo.title} marked as done");
                    } else if (direction == DismissDirection.startToEnd && todo.done == true) {
                      todo.done = false;
                      TodoList.myTodos.insert(todo.oldIndex, Todo(todo.title, todo.done = false));
                      TodoList.myTodos.remove(todo);
                      debugPrint("Todo ${todo.title} marked as undone");
                    } else if (direction == DismissDirection.endToStart) {
                      TodoList.myTodos.remove(todo);
                      debugPrint("Todo ${todo.title} deleted");
                    }
                    setState(() {});
                  },
                  key: todo.key,
                  background: Container(
                    color: Colors.green,
                    child: Icon(Icons.check),
                  ),
                  secondaryBackground: Container(
                    color: Colors.red,
                    child: Icon(Icons.delete),
                  ),
                  child: ListTile(
                    tileColor: calculateColor(todo),
                    key: todo.key,
                    title: TextField(
                      // TODO fix long press to drag todo instead of selecting the textfield. Short tap should be to select textfield!
                      // TODO Add app theme to textfield
                      style: (todo.done ? TextStyle(decoration: TextDecoration.lineThrough) : null),
                      controller: TextEditingController(text: todo.title),
                      decoration: null,
                      maxLength: 512,
                      maxLines: null,
                      textInputAction: TextInputAction.done,
                      onChanged: (text) {
                        //TODO check if correct
                        todo.title = text;
                      },
                      onEditingComplete: () {
                        //TODO check if correct
                        FocusScopeNode currentFocus = FocusScope.of(context);
                        currentFocus.unfocus();
                      },
                      onSubmitted: (text) {
                        //TODO check if correct
                        todo.title = text;
                        FocusScopeNode currentFocus = FocusScope.of(context);
                        currentFocus.unfocus();
                      },
                    ),
                  ),
                )
            ],
          ),
        )
      ]),
    );
  }
Другие вопросы по тегам