我用过这个部门。https://pub.dev/packages/flutter_reorderable_list 来创建可重新排序的列表,我做了并设置了样式。我没有使用带复选框的文本输入,而是生成了 10 个列表,其中 9 个是可点击的,但不是第一个。
class DragAndDropSubTasks extends StatefulWidget {
DragAndDropSubTasks({Key key, this.title}) : super(key: key);
final String title;
@override
_DragAndDropSubTasksState createState() => _DragAndDropSubTasksState();
}
class ItemData {
ItemData(this.title, this.key);
final String title;
// Each item in reorderable list needs stable and unique key
final Key key;
}
enum DraggingMode {
iOS,
Android,
}
class _DragAndDropSubTasksState extends State<DragAndDropSubTasks> {
List<ItemData> _items;
_DragAndDropSubTasksState() {
_items = List();
for (int i = 0; i < 1; i++) {
String label = "List item $i";
_items.add(ItemData(label, ValueKey(i)));
}
}
// Returns index of item with given key
int _indexOfKey(Key key) {
return _items.indexWhere((ItemData d) => d.key == key);
}
bool _reorderCallback(Key item, Key newPosition) {
int draggingIndex = _indexOfKey(item);
int newPositionIndex = _indexOfKey(newPosition);
// Uncomment to allow only even target reorder possition
// if (newPositionIndex % 2 == 1)
// return false;
final draggedItem = _items[draggingIndex];
setState(() {
debugPrint("Reordering $item -> $newPosition");
_items.removeAt(draggingIndex);
_items.insert(newPositionIndex, draggedItem);
});
return true;
}
void _reorderDone(Key item) {
final draggedItem = _items[_indexOfKey(item)];
debugPrint("Reordering finished for ${draggedItem.title}}");
}
//
// Reordering works by having ReorderableList widget in hierarchy
// containing ReorderableItems widgets
//
DraggingMode _draggingMode = DraggingMode.iOS;
Widget build(BuildContext context) {
return Scaffold(
body: ReorderableList(
onReorder: this._reorderCallback,
onReorderDone: this._reorderDone,
child: CustomScrollView(
// cacheExtent: 3000,
slivers: <Widget>[
SliverPadding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).padding.bottom),
sliver: SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
child: Item(
data: _items[index],
// first and last attributes affect border drawn during dragging
isFirst: index == 0,
isLast: index == _items.length - 1,
draggingMode: _draggingMode,
),
);
},
childCount: _items.length,
),
),
),
],
),
),
);
}
}
class Item extends StatelessWidget {
Item({
this.data,
this.isFirst,
this.isLast,
this.draggingMode,
});
final ItemData data;
final bool isFirst;
final bool isLast;
final DraggingMode draggingMode;
Widget _buildChild(BuildContext context, ReorderableItemState state) {
var device = MediaQuery.of(context).size;
BoxDecoration decoration;
if (state == ReorderableItemState.dragProxy ||
state == ReorderableItemState.dragProxyFinished) {
// slightly transparent background white dragging (just like on iOS)
} else {
bool placeholder = state == ReorderableItemState.placeholder;
decoration = BoxDecoration(
border: Border(
top: isFirst && !placeholder
? Divider.createBorderSide(context) //
: BorderSide.none,
bottom: isLast && placeholder
? BorderSide.none //
: Divider.createBorderSide(context)),
color: placeholder ? null : Colors.white);
}
// For iOS dragging mdoe, there will be drag handle on the right that triggers
// reordering; For android mode it will be just an empty container
Widget dragHandle = draggingMode == DraggingMode.iOS
? ReorderableListener(
child: Container(
height: device.height * 39 / 812,
padding: EdgeInsets.only(right: 18.0, left: 18.0),
margin: EdgeInsets.only(top: 7),
decoration: BoxDecoration(
borderRadius: new BorderRadius.only(
topRight: const Radius.circular(8.0),
bottomRight: const Radius.circular(8.0),
),
color: Color.fromRGBO(249, 248, 255, 1),
),
child: Center(child: BuildSvg('assets/svg/DragAndDropIcon.svg')),
),
)
: Container();
Widget content = Container(
decoration: decoration,
child: SafeArea(
top: false,
bottom: false,
child: Opacity(
// hide content for placeholder
opacity: state == ReorderableItemState.placeholder ? 0.0 : 1.0,
child: IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: 7),
width: device.width * 270 / 375,
margin: EdgeInsets.only(top: 7),
decoration: BoxDecoration(
borderRadius: new BorderRadius.only(
topLeft: const Radius.circular(8.0),
bottomLeft: const Radius.circular(8.0),
),
color: Color.fromRGBO(249, 248, 255, 1),
),
child: Stack(
children: <Widget>[
CheckBox('', false, Colors.white),
Container(
margin: EdgeInsets.only(left: 30),
child: TextFormField(
decoration: new InputDecoration(
border: InputBorder.none,
focusedBorder: InputBorder.none,
),
keyboardType: TextInputType.text,
),
),
],
)),
// Triggers the reordering
dragHandle,
],
),
),
)),
);
// For android dragging mode, wrap the entire content in DelayedReorderableListener
if (draggingMode == DraggingMode.Android) {
content = DelayedReorderableListener(
child: content,
);
}
return content;
}
@override
Widget build(BuildContext context) {
return ReorderableItem(
key: data.key, //
childBuilder: _buildChild,
);
}
}
输入和复选框不适用于第一个列表元素,但它们确实适用于其他元素