我想在拖放时实现
reorderableListView
小部件的动画功能,而不是拖动它如何通过单击按钮明确完成?
预期输出:-
这就是我所做的,删除所需的项目并在该索引上添加一个新项目。
代码:-
import 'package:flutter/material.dart';
void main() => runApp(const ReorderableApp());
class ReorderableApp extends StatelessWidget {
const ReorderableApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('ReorderableListView Sample')),
body: const ReorderableExample(),
),
);
}
}
class ReorderableExample extends StatefulWidget {
const ReorderableExample({super.key});
@override
State<ReorderableExample> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<ReorderableExample> {
final List<int> _items = List<int>.generate(4, (int index) => index);
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 300,
width: 300,
color: Colors.blue[100],
padding: const EdgeInsets.all(10),
child: Center(
child: ReorderableListView(
children: <Widget>[
for (int index = 0; index < _items.length; index += 1)
Container(
key: Key('$index'),
height: 60,
margin: const EdgeInsets.all(5),
color: Colors.blue[400],
alignment: Alignment.center,
child: Text('Item ${_items[index]}'),
),
],
onReorder: (int oldIndex, int newIndex) {},
),
),
),
const SizedBox(
height: 20,
),
FloatingActionButton(
onPressed: () {
setState(() {
final int item = _items.removeAt(0);
_items.insert(1, item);
});
},
child: const Icon(Icons.arrow_downward_sharp),
),
],
),
);
}
}
实际输出:-
如果你不介意没有动画,我会给你一个普通的 ListView:
ListView(
children: [
for(var i = 0; i < _items.length; i++) ItemWidget(_items[I])
],
)
请注意,这对许多孩子来说不是最佳解决方案。
您可以使用 great_list_view 包。
使用这个包的例子:
import 'package:flutter/material.dart';
import 'package:great_list_view/great_list_view.dart';
void main() {
Executor().warmUp();
runApp(App());
}
class App extends StatefulWidget {
@override
_AppState createState() => _AppState();
}
class _AppState extends State<App> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Test App',
home: SafeArea(
child: Scaffold(
body: Body(key: gkey),
)));
}
}
class Body extends StatefulWidget {
Body({Key? key}) : super(key: key);
@override
_BodyState createState() => _BodyState();
}
class _BodyState extends State<Body> {
late List<ItemData> currentList;
@override
void initState() {
super.initState();
currentList = listA;
}
void swapList() {
setState(() {
if (currentList == listA) {
currentList = listB;
} else {
currentList = listA;
}
});
}
@override
Widget build(BuildContext context) {
return Scrollbar(
child: AutomaticAnimatedListView<ItemData>(
list: currentList,
comparator: AnimatedListDiffListComparator<ItemData>(
sameItem: (a, b) => a.id == b.id,
sameContent: (a, b) =>
a.color == b.color && a.fixedHeight == b.fixedHeight),
itemBuilder: (context, item, data) => data.measuring
? Container(
margin: EdgeInsets.all(5), height: item.fixedHeight ?? 60)
: Item(data: item),
listController: controller,
addLongPressReorderable: true,
reorderModel: AutomaticAnimatedListReorderModel(currentList),
detectMoves: true,
),
);
}
}
class Item extends StatelessWidget {
final ItemData data;
const Item({Key? key, required this.data}) : super(key: key);
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => gkey.currentState?.swapList(),
child: AnimatedContainer(
height: data.fixedHeight ?? 60,
duration: const Duration(milliseconds: 500),
margin: EdgeInsets.all(5),
padding: EdgeInsets.all(15),
decoration: BoxDecoration(
color: data.color,
border: Border.all(color: Colors.black12, width: 0)),
child: Center(
child: Text(
'Item ${data.id}',
style: TextStyle(fontSize: 16),
))));
}
}
class ItemData {
final int id;
final Color color;
final double? fixedHeight;
const ItemData(this.id, [this.color = Colors.blue, this.fixedHeight]);
}
List<ItemData> listA = [
ItemData(1, Colors.orange),
ItemData(2),
ItemData(3),
ItemData(4, Colors.cyan),
ItemData(5),
ItemData(8, Colors.green)
];
List<ItemData> listB = [
ItemData(4, Colors.cyan),
ItemData(2),
ItemData(6),
ItemData(5, Colors.pink, 100),
ItemData(7),
ItemData(8, Colors.yellowAccent),
];
final controller = AnimatedListController();
final gkey = GlobalKey<_BodyState>();