从AnimatedList中添加或删除列表时,是否有办法平滑地调整列表项的位置?

问题描述

我有一个AnimatedList,我可以添加删除项目。我的问题是,当我将一个项目添加到列表的顶部时,其下方的项目会向下跳转以为其留出空间,而不是平稳过渡。

我发现this answer提供了一种解决方案,可以在移除项目时使它们顺利动画,但是我无法获得相同的解决方案来插入项目。

这是我到目前为止所拥有的。当该项目被添加到列表的顶部时,其下方的元素会平滑移动。但是,新元素的按比例放大过渡也随之发生。

class Foo extends StatefulWidget {
  Foo({Key key}) : super(key: key);

  final kDuration = const Duration(seconds: 1);

  @override
  _FooState createState() => _FooState();
}

class _FooState extends State<Foo> {
  final _key = GlobalKey<AnimatedListState>();
  List<Color> _items;
  int _counter;

  @override
  void initState() {
    super.initState();
    _items = <Color>[];
    _counter = 0;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Animated List Spike'),),body: AnimatedList(
        key: _key,initialItemCount: _items.length,itemBuilder: (context,index,animation) {
          return Stack(
            children: [
              // This transition creates the smooth shift-down effect.
              SizeTransition(
                sizefactor: animation.drive(Tween(begin: 0,end: 1)),child: Padding(
                  padding: const EdgeInsets.all(8.0),child: Container(
                    height: 64,color: Colors.transparent,// This is the content we actually want to show.
              Align(
                alignment: Alignment.topCenter,heightFactor: 0,child: SlideTransition(
                  position: Tween(
                    begin: Offset(0,-0.5),end: Offset(0,0),).animate(animation),child: ScaleTransition(
                    scale: CurveTween(curve: Curves.eaSEOutBack)
                        .animate(animation),child: Padding(
                      padding: const EdgeInsets.all(8.0),child: Card(
                        color: _items[index],child: Container(height: 64),],);
        },floatingActionButton: FloatingActionButton(
        onpressed: addItem,child: const Icon(Icons.add),);
  }

  void addItem() {
    _items.insert(0,Colors.primaries[_counter++ % Colors.primaries.length]);
    _key.currentState.insertItem(0,duration: widget.kDuration);
  }
}

有没有一种方法可以使元素平滑移动,然后然后引入新的元素比例?

解决方法

解决方案是使用Interval曲线。通过使一条曲线的末端在0.5标记处,另一条曲线从此开始,我能够使元素向下滑动,然后将新的元素比例放大。

CurveTween(
  curve: Interval(
    0.5,// Start halfway through the animation.
    1.0,// Stop at the end of the animation.
    curve: Curves.easeOutBack,),).animate(animation),

完整的问题解决方案:

itemBuilder: (context,index,animation) {
          return Stack(
            children: [
              SizeTransition(
                sizeFactor: animation.drive(
                  CurveTween(
                    curve: Interval(
                      0.0,0.5,curve: Curves.linear,child: Padding(
                  padding: const EdgeInsets.all(8.0),child: Container(
                    height: 64,color: Colors.transparent,Align(
                alignment: Alignment.topCenter,heightFactor: 0,child: ScaleTransition(
                  scale: CurveTween(
                    curve: Interval(
                      0.5,1.0,curve: Curves.easeOutBack,child: Padding(
                    padding: const EdgeInsets.all(8.0),child: Card(
                      color: _items[index],child: Container(height: 64),],);