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

#flutter #flutter-layout #flutter-sliver #reorderable-list

#flutter #flutter-layout #flutter-sliver #переупорядочиваемый список

Вопрос:

Я хочу, чтобы панель приложений Sliverapp была в верхней части экрана, а под переупорядочиваемым списком оставался sliverfill.

Я пробовал несколько решений и продолжаю получать разные ошибки с каждым из них. CustomScrollView с ReorderableListView, помещенным внутри свойства slivers, выдает ошибку «Ошибка утверждения: строка 4345 поз 14: ‘владелец._debugCurrentBuildTarget == this’: неверно. »

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

Комментарии:

1. Вы пытались поместить ReorderableListView в SliverToBoxAdapter?

2. Да, он просто показывает черный экран, когда я это делаю. Когда я включаю каркас (как показано в примере ниже), экран становится серым — того же цвета, что и фон, поскольку для темы приложения установлено значение dark. Но когда я пробую это без виджета Scaffold, он становится чисто черным. Я помещу пример кода в «ответ, потому что для комментария слишком много символов.

Ответ №1:

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

Ответ №2:

Показывает черный экран — см. Комментарий. Также выдает ошибку: во время выполнения функции 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 amp;amp; 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 amp;amp; 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();
                      },
                    ),
                  ),
                )
            ],
          ),
        )
      ]),
    );
  }