Flutter 颤振动画列表-将曲线动画添加到幻灯片转换

Flutter 颤振动画列表-将曲线动画添加到幻灯片转换,flutter,flutter-animation,Flutter,Flutter Animation,我已经成功地获得了一个动画列表,它将在新添加的项目中滑动。包装我的列表项的Dismissible小部件控制移除动画。我的问题是如何将某种类型的动画曲线添加到SlideTransition,以便控制新列表项在滑入时的显示方式。到目前为止,我的情况如下: @override Widget build(BuildContext context) { final checklists = Provider.of<Checklists>(context); return AnimatedLi

我已经成功地获得了一个
动画列表
,它将在新添加的项目中滑动。包装我的列表项的
Dismissible
小部件控制移除动画。我的问题是如何将某种类型的动画曲线添加到
SlideTransition
,以便控制新列表项在滑入时的显示方式。到目前为止,我的情况如下:

@override
Widget build(BuildContext context) {
final checklists = Provider.of<Checklists>(context);

return AnimatedList(
  key: listKey,
  initialItemCount: checklists.lists.length,
  itemBuilder: (ctx, i, animation) {
    return SlideTransition(
      position: CurvedAnimation(parent: ).drive(child)  // <- this line needs changing
      child: _buildListItem(checklists.lists[i], i),          
    );
  },      
);
}
它工作得很好,但缺少曲线缓和。有什么想法吗

编辑 为了清晰起见,这里是完整的.dart文件,我从父窗口小部件中插入了一个新项目:

GlobalKey<AnimatedListState> recentListsAnimationKey = GlobalKey();

class RecentLists extends StatefulWidget {
  @override
  _RecentListsState createState() => _RecentListsState();
}

class _RecentListsState extends State<RecentLists>
    with TickerProviderStateMixin {
  Widget _buildListItem(Checklist list, int listIndex) {
    return Dismissible(
      key: ObjectKey(list.id),
      direction: DismissDirection.endToStart,
      background: Container(
        alignment: AlignmentDirectional.centerEnd,
        color: Theme.of(context).accentColor,
        child: Padding(
          padding: EdgeInsets.fromLTRB(0.0, 0.0, 10.0, 0.0),
          child: Icon(
            Icons.delete,
            color: Colors.white,
          ),
        ),
      ),
      child: ListTile(
        onTap: () {
          Navigator.push(
            context,
            MaterialPageRoute(
              builder: (ctx) => ListItemsScreen(list.id),
            ),
          );
        },
        title: Text(list.name),
        leading: Checkbox(
          value: list.completed,
          onChanged: (value) {
            setState(() {
              list.completed = value;
            });
          },
        ),
      ),
      onDismissed: (direction) {
        _onDeleteList(list, listIndex);
      },
    );
  }

  void _onDeleteList(Checklist list, int listIndex) {
    Provider.of<Checklists>(context).deleteList(list.id);
    recentListsAnimationKey.currentState
        .removeItem(listIndex, (_, __) => Container());

    Scaffold.of(context).showSnackBar(
      SnackBar(
        action: SnackBarAction(
          label: 'UNDO',
          onPressed: () {
            Provider.of<Checklists>(context).undoDeleteList(list, listIndex);
            recentListsAnimationKey.currentState
                .insertItem(listIndex, duration: Duration(milliseconds: 100));
          },
        ),
        content: Text(
          'List deleted',
          style: TextStyle(color: Theme.of(context).accentColor),
        ),
      ),
    );
  }

  AnimationController _controller;
  Animation<Offset> _position;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: Duration(milliseconds: 200),
      vsync: this,
    );
    _position = Tween(
      begin: Offset(0.5, 0),
      end: Offset(0.0, 0),
    ).animate(
      CurvedAnimation(
        parent: _controller,
        curve: Curves.decelerate,
      ),
    );
    _controller.forward();
  }

  @override
  void dispose() {
    super.dispose();
    _controller.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final checklists = Provider.of<Checklists>(context);

    return AnimatedList(
      key: recentListsAnimationKey, 
      initialItemCount: checklists.lists.length,
      itemBuilder: (ctx, i, animation) {
        return SlideTransition(
          position: _position,
          child: _buildListItem(checklists.lists[i], i),
        );
      },
    );
  }
}
GlobalKey-recentListsAnimationKey=GlobalKey();
类RecentList扩展StatefulWidget{
@凌驾
_RecentListsState createState()=>\u RecentListsState();
}
类_RecentListsState扩展状态
使用TickerProviderStateMixin{
小部件_buildListItem(检查表列表,int listIndex){
可驳回的回报(
key:ObjectKey(list.id),
方向:DismissDirection.endToStart,
背景:集装箱(
对齐:对齐方向.centerEnd,
颜色:主题。背景。强调颜色,
孩子:填充(
填充:来自LTRB(0.0,0.0,10.0,0.0)的边缘设置,
子:图标(
图标。删除,
颜色:颜色,白色,
),
),
),
孩子:ListTile(
onTap:(){
导航器。推(
上下文
材料路线(
生成器:(ctx)=>ListItemsScreen(list.id),
),
);
},
标题:文本(列表名称),
前导:复选框(
值:list.completed,
一旦更改:(值){
设置状态(){
list.completed=值;
});
},
),
),
onDismissed:(方向){
_onDeleteList(列表、列表索引);
},
);
}
作废删除列表(检查表列表、int列表索引){
Provider.of(context.deleteList)(list.id);
recentListsAnimationKey.currentState
.removietem(listIndex,(u,uu)=>Container());
Scaffold.of(上下文).showSnackBar(
小吃条(
行动:SnackBarAction(
标签:“撤消”,
已按下:(){
Provider.of(context).undoDeleteList(list,listIndex);
recentListsAnimationKey.currentState
.insertItem(列表索引,持续时间:持续时间(毫秒:100));
},
),
内容:文本(
“已删除列表”,
样式:TextStyle(颜色:Theme.of(context).accentColor),
),
),
);
}
动画控制器_控制器;
动画位置;
@凌驾
void initState(){
super.initState();
_控制器=动画控制器(
持续时间:持续时间(毫秒:200),
vsync:这个,,
);
_位置=吐温(
开始:偏移量(0.5,0),
结束:偏移量(0.0,0),
).制作动画(
曲线化(
父节点:_控制器,
曲线:曲线。减速,
),
);
_controller.forward();
}
@凌驾
无效处置(){
super.dispose();
_controller.dispose();
}
@凌驾
小部件构建(构建上下文){
最终检查表=提供者(上下文);
返回动画列表(
键:recentListsAnimationKey,
initialItemCount:checklists.lists.length,
itemBuilder:(ctx、i、动画){
返回幻灯片转换(
位置:_位置,
子项:_buildListItem(checklist.lists[i],i),
);
},
);
}
}
这里是我在列表中插入新项目的地方。不显示幻灯片动画

void createNewList(BuildContext context) {
  if (nameController.text.isNotEmpty) {
    Provider.of<Checklists>(context).addList(nameController.text);
    recentListsAnimationKey.currentState.insertItem(0, duration: Duration(milliseconds: 100));
    nameController.clear();
   }
    Navigator.of(context).pop();
  }
void createNewList(BuildContext上下文){
if(nameController.text.isNotEmpty){
Provider.of(context.addList)(nameController.text);
recentListsAnimationKey.currentState.insertItem(0,持续时间:持续时间(毫秒:100));
nameController.clear();
}
Navigator.of(context.pop();
}

flatter
中,“动画”只是一个类,它根据AnimationController提供的百分比从开始到结束更改数据。您必须准备
位置
哪个
动画实例

class DemoWidget扩展了StatefulWidget{
@凌驾
_DemoWidgetState createState();
}
类_DemoWidgetState使用TickerProviderStateMixin扩展StateMixin{
动画控制器_控制器;
动画位置;
@凌驾
小部件构建(构建上下文){
最终检查表=提供者(上下文);
返回动画列表(
键:listKey,
initialItemCount:checklists.lists.length,
itemBuilder:(ctx、i、动画){
返回幻灯片转换(
位置:_位置,
子项:_buildListItem(checklist.lists[i],i),
);
},      
);
}
@凌驾
initState(){
super.initState();
_controller=AnimationController(持续时间:const-duration(毫秒:2000),vsync:this);
_位置=Tween(开始:偏移(0.2,0),结束:偏移(0.0,0))。动画(曲线动画(父:控制器,曲线:曲线。减速));
_controller.forward();
}
@凌驾
处置{
_controller.dispose();
super.dispose();
}
}
使用链接到偏移线之间的函数。您的itemBuilder应该如下所示:

itemBuilder: (ctx, i, animation) {
    return SlideTransition(
      position: animation.drive(Tween(begin: Offset(2, 0.0), end: Offset(0.0, 0.0))
            .chain(CurveTween(curve: Curves.elasticInOut))),
      child: _buildListItem(checklists.lists[i], i),          
    );
  },

这适用于列表中的初始项目,但当我添加项目时,它不会设置动画。如何设置向列表中添加项目的动画?:/请提出新问题并在此处发布此链接。或者您可以通过
\u控制器
控制动画。我编辑了我的问题,以显示更多代码,从而提供更好的上下文。幻灯片动画现在在最初加载列表时工作,但添加新项目时没有幻灯片动画。
class DemoWidget extends StatefulWidget {
  @override
  _DemoWidgetState createState() => _DemoWidgetState();
}

class _DemoWidgetState extends State<DemoWidget>with TickerProviderStateMixin {
  AnimationController _controller;
  Animation<Offset> _position;

  @override
  Widget build(BuildContext context) {
    final checklists = Provider.of<Checklists>(context);

    return AnimatedList(
      key: listKey,
      initialItemCount: checklists.lists.length,
      itemBuilder: (ctx, i, animation) {
        return SlideTransition(
          position: _position,
          child: _buildListItem(checklists.lists[i], i),          
        );
      },      
    );
  }

  @override
  initState() {
    super.initState();
    _controller = AnimationController(duration: const Duration(milliseconds: 2000), vsync: this);
    _position = Tween(begin: Offset(0.2, 0), end: Offset(0.0, 0)).animate(CurvedAnimation(parent: _controller, curve: Curves.decelerate));
    _controller.forward();
  }

  @override
  dispose() {
    _controller.dispose();
    super.dispose();
  }
}
itemBuilder: (ctx, i, animation) {
    return SlideTransition(
      position: animation.drive(Tween(begin: Offset(2, 0.0), end: Offset(0.0, 0.0))
            .chain(CurveTween(curve: Curves.elasticInOut))),
      child: _buildListItem(checklists.lists[i], i),          
    );
  },