Flutter 可排序拖放 ListView
Flutter Sortable Drag And Drop ListView
所以我开始学习 Flutter 并想使用 material 设计拖放列表,就像在 material 指南网站上看到的那样。
到目前为止,我尝试过的所有库与它相比都显得很垃圾。是否有一个我缺少的好库或一个原生的 Flutter 小部件?
检查 knopp/flutter_reorderable_list。它做到了这一点。
它真的很流畅,没有性能问题,能够处理成千上万的项目。
然而,它的实现并不像通常的 flutter 小部件那样容易。
如果您遇到困难,我建议您使用我创建的小部件将 flutter/ReorderableListView
s 移植到 knopp/ReorderableList
。
这个小部件非常易于使用,但是它没有提供相同的灵活性,并且由于它与 children
List
一起使用,所以它的可扩展性不如原来的小部件。
这是 code for ReorderableListSimple and this is the demo。
我试过 flutter_reorderable_list and dragable_flutter_list 但其中 none 工作正常 - 拖动过程中出现了一些不需要的伪影。
所以我尝试制定自己的解决方案:
ListView.builder(
itemBuilder: (context, index) => buildRow(index),
itemCount: trackList.length,
),
Widget buildRow(int index) {
final track = trackList[index];
ListTile tile = ListTile(
title: Text('${track.getName()}'),
);
Draggable draggable = LongPressDraggable<Track>(
data: track,
axis: Axis.vertical,
maxSimultaneousDrags: 1,
child: tile,
childWhenDragging: Opacity(
opacity: 0.5,
child: tile,
),
feedback: Material(
child: ConstrainedBox(
constraints:
BoxConstraints(maxWidth: MediaQuery.of(context).size.width),
child: tile,
),
elevation: 4.0,
),
);
return DragTarget<Track>(
onWillAccept: (track) {
return trackList.indexOf(track) != index;
},
onAccept: (track) {
setState(() {
int currentIndex = trackList.indexOf(track);
trackList.remove(track);
trackList.insert(currentIndex > index ? index : index - 1, track);
});
},
builder: (BuildContext context, List<Track> candidateData,
List<dynamic> rejectedData) {
return Column(
children: <Widget>[
AnimatedSize(
duration: Duration(milliseconds: 100),
vsync: this,
child: candidateData.isEmpty
? Container()
: Opacity(
opacity: 0.0,
child: tile,
),
),
Card(
child: candidateData.isEmpty ? draggable : tile,
)
],
);
},
);
}
我想,这不是最好的解决方案,我可能会进一步更改它,但目前效果很好
Flutter 本身提供了一个(Material)ReorderableListView class.
可以使用原生的flutter widget,ReorderableListView
来实现,这里是实现的例子。
List<String> _list = ["Apple", "Ball", "Cat", "Dog", "Elephant"];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: ReorderableListView(
children: _list.map((item) => ListTile(key: Key("${item}"), title: Text("${item}"), trailing: Icon(Icons.menu),)).toList(),
onReorder: (int start, int current) {
// dragging from top to bottom
if (start < current) {
int end = current - 1;
String startItem = _list[start];
int i = 0;
int local = start;
do {
_list[local] = _list[++local];
i++;
} while (i < end - start);
_list[end] = startItem;
}
// dragging from bottom to top
else if (start > current) {
String startItem = _list[start];
for (int i = start; i > current; i--) {
_list[i] = _list[i - 1];
}
_list[current] = startItem;
}
setState(() {});
},
),
);
}
Flutter 团队推出了 ReorderableListView 小部件。
ReorderableListView(
children: <Widget>[
for (var item in appState.menuButtons)
Text('data')
],
)
所以我开始学习 Flutter 并想使用 material 设计拖放列表,就像在 material 指南网站上看到的那样。
到目前为止,我尝试过的所有库与它相比都显得很垃圾。是否有一个我缺少的好库或一个原生的 Flutter 小部件?
检查 knopp/flutter_reorderable_list。它做到了这一点。 它真的很流畅,没有性能问题,能够处理成千上万的项目。
然而,它的实现并不像通常的 flutter 小部件那样容易。
如果您遇到困难,我建议您使用我创建的小部件将 flutter/ReorderableListView
s 移植到 knopp/ReorderableList
。
这个小部件非常易于使用,但是它没有提供相同的灵活性,并且由于它与 children
List
一起使用,所以它的可扩展性不如原来的小部件。
这是 code for ReorderableListSimple and this is the demo。
我试过 flutter_reorderable_list and dragable_flutter_list 但其中 none 工作正常 - 拖动过程中出现了一些不需要的伪影。 所以我尝试制定自己的解决方案:
ListView.builder(
itemBuilder: (context, index) => buildRow(index),
itemCount: trackList.length,
),
Widget buildRow(int index) {
final track = trackList[index];
ListTile tile = ListTile(
title: Text('${track.getName()}'),
);
Draggable draggable = LongPressDraggable<Track>(
data: track,
axis: Axis.vertical,
maxSimultaneousDrags: 1,
child: tile,
childWhenDragging: Opacity(
opacity: 0.5,
child: tile,
),
feedback: Material(
child: ConstrainedBox(
constraints:
BoxConstraints(maxWidth: MediaQuery.of(context).size.width),
child: tile,
),
elevation: 4.0,
),
);
return DragTarget<Track>(
onWillAccept: (track) {
return trackList.indexOf(track) != index;
},
onAccept: (track) {
setState(() {
int currentIndex = trackList.indexOf(track);
trackList.remove(track);
trackList.insert(currentIndex > index ? index : index - 1, track);
});
},
builder: (BuildContext context, List<Track> candidateData,
List<dynamic> rejectedData) {
return Column(
children: <Widget>[
AnimatedSize(
duration: Duration(milliseconds: 100),
vsync: this,
child: candidateData.isEmpty
? Container()
: Opacity(
opacity: 0.0,
child: tile,
),
),
Card(
child: candidateData.isEmpty ? draggable : tile,
)
],
);
},
);
}
我想,这不是最好的解决方案,我可能会进一步更改它,但目前效果很好
Flutter 本身提供了一个(Material)ReorderableListView class.
可以使用原生的flutter widget,ReorderableListView
来实现,这里是实现的例子。
List<String> _list = ["Apple", "Ball", "Cat", "Dog", "Elephant"];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: ReorderableListView(
children: _list.map((item) => ListTile(key: Key("${item}"), title: Text("${item}"), trailing: Icon(Icons.menu),)).toList(),
onReorder: (int start, int current) {
// dragging from top to bottom
if (start < current) {
int end = current - 1;
String startItem = _list[start];
int i = 0;
int local = start;
do {
_list[local] = _list[++local];
i++;
} while (i < end - start);
_list[end] = startItem;
}
// dragging from bottom to top
else if (start > current) {
String startItem = _list[start];
for (int i = start; i > current; i--) {
_list[i] = _list[i - 1];
}
_list[current] = startItem;
}
setState(() {});
},
),
);
}
Flutter 团队推出了 ReorderableListView 小部件。
ReorderableListView(
children: <Widget>[
for (var item in appState.menuButtons)
Text('data')
],
)