Как мне поместить 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();
},
),
),
)
],
),
)
]),
);
}