How to animate the items rendered initially using Animated List in flutter

前端 未结 1 1686
小蘑菇
小蘑菇 2021-01-18 12:31

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 n

1条回答
  •  隐瞒了意图╮
    2021-01-18 12:53

    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.

    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
        });
      });
    }
    

    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 = [];
    final GlobalKey _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);
          });
        });
      }
    }
    

    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 {
      var _listItems = [];
      final GlobalKey _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 animation) {
                return SlideTransition(
                  position: CurvedAnimation(
                    curve: Curves.easeOut,
                    parent: animation,
                  ).drive((Tween(
                    begin: Offset(1, 0),
                    end: Offset(0, 0),
                  ))),
                  child: deletedItem,
                );
              });
            });
          });
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            actions: [
              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(
                  begin: Offset(1, 0),
                  end: Offset(0, 0),
                ))),
                child: _listItems[index],
              );
            },
          ),
        );
      }
    }
    

    0 讨论(0)
提交回复
热议问题