#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();
},
),
),
)
],
),
)
]),
);
}