如何在flutter中使用“动画列表"对最初渲染的项目进行动画处理 [英] How to animate the items rendered initially using Animated List in flutter

查看:61
本文介绍了如何在flutter中使用“动画列表"对最初渲染的项目进行动画处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Flutter中使用Animated List来加载列表类,在添加或删除项目时,动画有效,但是在最初加载列表时,动画不起作用.最初加载列表时,是否可以为项目设置动画.

I am using Animated List in flutter to load a list class, while adding or removing the items, the animation works but when the list is initially loaded, the animation does not work. Is there a way to animate items when initially loading the list.

class AnimationTest extends StatefulWidget {
  @override
  _AnimationTestState createState() => _AnimationTestState();
}

class _AnimationTestState extends State<AnimationTest> with SingleTickerProviderStateMixin {
  AnimationController _controller;

  @override
  void initState() {
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 1),
    );
    super.initState();
  }

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

  @override
  Widget build(BuildContext context) {
    return AnimatedList(
      key: _listKey,
      initialItemCount: 3,
      itemBuilder: (BuildContext context, int index, Animation animation) {
        return SlideTransition(
          position: animation.drive(Tween<Offset>(begin: Offset(1.0, 0.0), end: Offset.zero)
              .chain(CurveTween(curve: Curves.decelerate))),
          child: Row(
            children: <Widget>[
              Expanded(
                child: InkWell(
                  onTap: () => _listKey.currentState.insertItem(0,duration: Duration(milliseconds: 600)),
                  child: Container(
                      padding: EdgeInsets.only(left: 10, right: 10),
                      height: 100,
                      child: Card(
                        margin: EdgeInsets.symmetric(vertical: 4.0),
                        color: Theme.of(context).backgroundColor,
                      )),
                ),
              ),
            ],
          ),
        );
      },
    );
  }
}

推荐答案

因为AnimatedList仅在添加/删除列表中的项目时可以设置动画.您需要使用AnimatedListState中的insertItemremoveItem分别添加每个项目.一种获得良好加载效果的方法是延迟每次插入/删除项目的时间.

Because AnimatedList can only animate when adding/removing item in the list. You need to add each item individually by using insertItem or removeItem from AnimatedListState. One way to achieve a nice loading effect is to delay each time you insert/remove item.

这里是链接Future的代码,以便在指定的延迟后将每个项目一个接一个地加载

Here is the code to chain Future so that each item is loaded one after another after a specified delay

var future = Future(() {});
for (var i = 0; i < fetchedList.length; i++) {
  future = future.then((_) {
    return Future.delayed(Duration(milliseconds: 100), () {
      // add/remove item
    });
  });
}

从此处可以创建loadItems()方法,以初始化initState()AnimatedList中的所有项目.记住要同时更新基础数据结构(_listItems)和AnimatedList本身,以使其正常工作.

From there you can create a loadItems() method to initialize all items in the AnimatedList in initState(). Remember to update both the underlying data structure (_listItems) and AnimatedList itself for it to work.

var _listItems = <Widget>[];
final GlobalKey<AnimatedListState> _listKey = GlobalKey();

@override
void initState() {
  super.initState();

  _loadItems();
}

void _loadItems() {
  // fetching data from web api, local db...
  final fetchedList = [
    ListTile(
      title: Text('Economy'),
      trailing: Icon(Icons.directions_car),
    ),
    ListTile(
      title: Text('Comfort'),
      trailing: Icon(Icons.motorcycle),
    ),
    ListTile(
      title: Text('Business'),
      trailing: Icon(Icons.flight),
    ),
  ];

  var future = Future(() {});
  for (var i = 0; i < fetchedList.length; i++) {
    future = future.then((_) {
      return Future.delayed(Duration(milliseconds: 100), () {
        _listItems.add(fetchedList[i]);
        _listKey.currentState.insertItem(i);
      });
    });
  }
}

这是完整的示例.我在应用栏中添加了2个按钮,以便您可以播放动画

This is the complete example. I added 2 buttons in the app bar so you can play around with the animations

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'YourAwesomeApp',
      home: PageWithAnimatedList(),
    );
  }
}

class PageWithAnimatedList extends StatefulWidget {
  @override
  _PageWithAnimatedListState createState() => _PageWithAnimatedListState();
}

class _PageWithAnimatedListState extends State<PageWithAnimatedList> {
  var _listItems = <Widget>[];
  final GlobalKey<AnimatedListState> _listKey = GlobalKey();

  @override
  void initState() {
    super.initState();

    _loadItems();
  }

  void _loadItems() {
    // fetching data from web api, db...
    final fetchedList = [
      ListTile(
        title: Text('Economy'),
        trailing: Icon(Icons.directions_car),
      ),
      ListTile(
        title: Text('Comfort'),
        trailing: Icon(Icons.motorcycle),
      ),
      ListTile(
        title: Text('Business'),
        trailing: Icon(Icons.flight),
      ),
    ];

    var future = Future(() {});
    for (var i = 0; i < fetchedList.length; i++) {
      future = future.then((_) {
        return Future.delayed(Duration(milliseconds: 100), () {
          _listItems.add(fetchedList[i]);
          _listKey.currentState.insertItem(_listItems.length - 1);
        });
      });
    }
  }

  void _unloadItems() {
    var future = Future(() {});
    for (var i = _listItems.length - 1; i >= 0; i--) {
      future = future.then((_) {
        return Future.delayed(Duration(milliseconds: 100), () {
          final deletedItem = _listItems.removeAt(i);
          _listKey.currentState.removeItem(i,
              (BuildContext context, Animation<double> animation) {
            return SlideTransition(
              position: CurvedAnimation(
                curve: Curves.easeOut,
                parent: animation,
              ).drive((Tween<Offset>(
                begin: Offset(1, 0),
                end: Offset(0, 0),
              ))),
              child: deletedItem,
            );
          });
        });
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        actions: <Widget>[
          IconButton(icon: Icon(Icons.add), onPressed: _loadItems),
          IconButton(icon: Icon(Icons.remove), onPressed: _unloadItems)
        ],
      ),
      body: AnimatedList(
        key: _listKey,
        padding: EdgeInsets.only(top: 10),
        initialItemCount: _listItems.length,
        itemBuilder: (context, index, animation) {
          return SlideTransition(
            position: CurvedAnimation(
              curve: Curves.easeOut,
              parent: animation,
            ).drive((Tween<Offset>(
              begin: Offset(1, 0),
              end: Offset(0, 0),
            ))),
            child: _listItems[index],
          );
        },
      ),
    );
  }
}

这篇关于如何在flutter中使用“动画列表"对最初渲染的项目进行动画处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆