我正在颤动中创建一个 AnimatedList ,我想要的唯一动画是在按下项目的删除按钮后删除列表项时。该项目删除并消失,但我希望它在删除时为垂直折叠设置动画(我使用 SizeTransition)。动画似乎没有运行。
我认为这与我实现RemovedItemBuilder类的方式有关,但它几乎与 Flutter 文档中SizeTransition类的示例相同。
(当在RemovedItemBuilder类的构建方法中返回DirectMessagePreview的实例作为临时占位符时,我故意传入了索引“99”和名称“哇” )
import 'package:flutter/material.dart';
class DirectMessages extends StatefulWidget {
const DirectMessages({Key? key}) : super(key: key);
@override
_DirectMessagesState createState() => _DirectMessagesState();
}
class _DirectMessagesState extends State<DirectMessages>
with TickerProviderStateMixin {
final GlobalKey<AnimatedListState> listkey = GlobalKey<AnimatedListState>();
late var list = [1, 2, 3, 4, 5];
void removeDirectMessage(int index) {
print(index);
setState(() {
list.removeAt(index - 1);
});
print(list);
}
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
child: AnimatedList(
key: listkey,
initialItemCount: list.length,
itemBuilder: (context, index, animation) {
return DirectMessagePreview(
name: list[index].toString(),
index: index,
);
}));
}
}
class DirectMessagePreview extends StatefulWidget {
final int index;
final String name;
const DirectMessagePreview({
Key? key,
required this.index,
required this.name,
}) : super(key: key);
@override
_DirectMessagePreviewState createState() => _DirectMessagePreviewState();
}
class _DirectMessagePreviewState extends State<DirectMessagePreview>
with TickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
void initState() {
super.initState();
}
void _move(DragUpdateDetails details) {
double? delta = details.primaryDelta;
if (delta != null) this._controller.value -= delta / 112;
}
void _handeDragEnd(DragEndDetails details) {
double velocity = details.velocity.pixelsPerSecond.dx;
// negative velocity : left swipe, animation forward
// positive velocity : right swipe, animation reverses
if (velocity > 0.0) {
_controller.fling(velocity: -1.0);
} else if (velocity < 0.0) {
_controller.fling(velocity: 1.0);
}
}
Widget _buildRemovedItem(
int item, BuildContext context, Animation<double> animation) {
return RemovedItemBuilder();
}
@override
Widget build(BuildContext context) {
_controller = AnimationController(
duration: Duration(milliseconds: 300),
reverseDuration: Duration(milliseconds: 30),
vsync: this);
_animation = CurvedAnimation(parent: _controller, curve: Curves.linear);
return GestureDetector(
onHorizontalDragUpdate: _move,
onHorizontalDragEnd: _handeDragEnd,
child: Stack(children: <Widget>[
Positioned.fill(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () {},
child: Text('Mute', style: TextStyle(color: Colors.white)),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.grey),
splashFactory: NoSplash.splashFactory,
shape:
MaterialStateProperty.all(BeveledRectangleBorder()))),
TextButton(
onPressed: () {
//print('removing index: ' + widget.index.toString());
AnimatedList.of(context).removeItem(
widget.index,
(context, animation) {
return _buildRemovedItem(
widget.index, context, animation);
},
);
},
child: Text('Delete', style: TextStyle(color: Colors.white)),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.red),
splashFactory: NoSplash.splashFactory,
shape:
MaterialStateProperty.all(BeveledRectangleBorder()))),
],
),
),
SlideTransition(
position: Tween<Offset>(begin: Offset.zero, end: Offset(-.30, 0))
.animate(_animation),
child: Container(
color: Colors.white,
padding:
EdgeInsets.only(left: 16, right: 16, top: 16, bottom: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Icon(Icons.face), //CircleAvatar()
SizedBox(width: 12),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(widget.name, style: TextStyle(fontSize: 16)),
SizedBox(height: 6),
Text('Hey this is stan',
style: TextStyle(
fontSize: 12, color: Colors.grey[600]))
],
)
],
),
Text('yesterday')
],
)),
),
]),
);
}
}
class RemovedItemBuilder extends StatefulWidget {
const RemovedItemBuilder({Key? key}) : super(key: key);
@override
_RemovedItemBuilderState createState() => _RemovedItemBuilderState();
}
class _RemovedItemBuilderState extends State<RemovedItemBuilder>
with SingleTickerProviderStateMixin {
late final AnimationController _controller = AnimationController(
duration: const Duration(milliseconds: 300),
vsync: this,
);
late final Animation<double> _animation =
CurvedAnimation(parent: _controller, curve: Curves.fastOutSlowIn);
@override
void dispose() {
super.dispose();
_controller.dispose();
}
@override
Widget build(BuildContext context) {
return SizeTransition(
sizeFactor: _animation,
axis: Axis.vertical,
axisAlignment: -1,
child: DirectMessagePreview(index: 99, name: 'wow'));
}
}