Flutter 颤振动画列表:为整个列表设置动画

Flutter 颤振动画列表:为整个列表设置动画,flutter,dart,flutter-animatedlist,Flutter,Dart,Flutter Animatedlist,我正在尝试实现颤振的。我想要实现的是allready拥有一个元素列表,然后在列表中逐个插入它们,总持续时间为1秒 例如:我有一个5个容器的列表(一个红色的,一个蓝色的,一个绿色的,一个粉色的和一个白色的)。我希望在列表视图中滑动每个容器 我现在希望在启动时,此列表显示在以下时间戳中: 0..200ms:红色容器 200..400ms:蓝色容器 400..600ms:绿色容器 600..800ms:粉红色容器 800..1000ms:白色容器 这样,整个列表需要1秒来构建,1个容器制作动画所需的时

我正在尝试实现颤振的。我想要实现的是allready拥有一个元素列表,然后在列表中逐个插入它们,总持续时间为1秒

例如:我有一个5个容器的列表(一个红色的,一个蓝色的,一个绿色的,一个粉色的和一个白色的)。我希望在列表视图中滑动每个容器

我现在希望在启动时,此列表显示在以下时间戳中:

0..200ms:红色容器

200..400ms:蓝色容器

400..600ms:绿色容器

600..800ms:粉红色容器

800..1000ms:白色容器

这样,整个列表需要1秒来构建,1个容器制作动画所需的时间为
1/n
秒,列表中索引
i
处的每个容器应在
i*(1/n)
秒开始制作动画。然而,我能找到的所有文档或示例都只是简单地显示一个按钮,然后在列表中插入一个新项目,而我希望通过动画的方式显示一个已经创建的列表。

您尝试过吗

您可以简单地使用它并在提到的时间之后插入项目。像这样:

void startTimer() {
  const oneSec = const Duration(milliseconds: 1000);
  _timer = new Timer.periodic(
    oneSec,
    (Timer timer) {
      _insert();
      if(_list.length == 10){
      timer.cancel();
      }
    },
  );
省道板上的完整代码:

/// Flutter code sample for AnimatedList

// This sample application uses an [AnimatedList] to create an effect when
// items are removed or added to the list.
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const AnimatedListSample());
}

class AnimatedListSample extends StatefulWidget {
  const AnimatedListSample({Key? key}) : super(key: key);

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

class _AnimatedListSampleState extends State<AnimatedListSample> {
  final GlobalKey<AnimatedListState> _listKey = GlobalKey<AnimatedListState>();
  late ListModel<int> _list;
  int? _selectedItem;
  late int
      _nextItem; // The next item inserted when the user presses the '+' button.

  Timer? _timer;
  @override
  void initState() {
    super.initState();
    _list = ListModel<int>(
      listKey: _listKey,
      initialItems: <int>[0, 1, 2],
      removedItemBuilder: _buildRemovedItem,
    );
    _nextItem = 3;
    startTimer();
  }

  void startTimer() {
  const oneSec = const Duration(milliseconds: 1000);
  _timer = new Timer.periodic(
    oneSec,
    (Timer timer) {
      _insert();
      if(_list.length == 10){
      timer.cancel();
      }
    },
  );
}
  
  @override
void dispose() {
  _timer!.cancel();
  super.dispose();
}

  // Used to build list items that haven't been removed.
  Widget _buildItem(
      BuildContext context, int index, Animation<double> animation) {
    return CardItem(
      animation: animation,
      item: _list[index],
      selected: _selectedItem == _list[index],
      onTap: () {
        setState(() {
          _selectedItem = _selectedItem == _list[index] ? null : _list[index];
        });
      },
    );
  }

  // Used to build an item after it has been removed from the list. This
  // method is needed because a removed item remains visible until its
  // animation has completed (even though it's gone as far this ListModel is
  // concerned). The widget will be used by the
  // [AnimatedListState.removeItem] method's
  // [AnimatedListRemovedItemBuilder] parameter.
  Widget _buildRemovedItem(
      int item, BuildContext context, Animation<double> animation) {
    return CardItem(
      animation: animation,
      item: item,
      selected: false,
      // No gesture detector here: we don't want removed items to be interactive.
    );
  }

  // Insert the "next item" into the list model.
  void _insert() {
    final int index =
        _selectedItem == null ? _list.length : _list.indexOf(_selectedItem!);
    _list.insert(index, _nextItem++);
  }

  // Remove the selected item from the list model.
  void _remove() {
    if (_selectedItem != null) {
      _list.removeAt(_list.indexOf(_selectedItem!));
      setState(() {
        _selectedItem = null;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('AnimatedList'),
          actions: <Widget>[
            IconButton(
              icon: const Icon(Icons.add_circle),
              onPressed: _insert,
              tooltip: 'insert a new item',
            ),
            IconButton(
              icon: const Icon(Icons.remove_circle),
              onPressed: _remove,
              tooltip: 'remove the selected item',
            ),
          ],
        ),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: AnimatedList(
            key: _listKey,
            initialItemCount: _list.length,
            itemBuilder: _buildItem,
          ),
        ),
      ),
    );
  }
}

typedef RemovedItemBuilder = Widget Function(
    int item, BuildContext context, Animation<double> animation);

/// Keeps a Dart [List] in sync with an [AnimatedList].
///
/// The [insert] and [removeAt] methods apply to both the internal list and
/// the animated list that belongs to [listKey].
///
/// This class only exposes as much of the Dart List API as is needed by the
/// sample app. More list methods are easily added, however methods that
/// mutate the list must make the same changes to the animated list in terms
/// of [AnimatedListState.insertItem] and [AnimatedList.removeItem].
class ListModel<E> {
  ListModel({
    required this.listKey,
    required this.removedItemBuilder,
    Iterable<E>? initialItems,
  }) : _items = List<E>.from(initialItems ?? <E>[]);

  final GlobalKey<AnimatedListState> listKey;
  final RemovedItemBuilder removedItemBuilder;
  final List<E> _items;

  AnimatedListState? get _animatedList => listKey.currentState;

  void insert(int index, E item) {
    _items.insert(index, item);
    _animatedList!.insertItem(index);
  }

  E removeAt(int index) {
    final E removedItem = _items.removeAt(index);
    if (removedItem != null) {
      _animatedList!.removeItem(
        index,
        (BuildContext context, Animation<double> animation) {
          return removedItemBuilder(index, context, animation);
        },
      );
    }
    return removedItem;
  }

  int get length => _items.length;

  E operator [](int index) => _items[index];

  int indexOf(E item) => _items.indexOf(item);
}

/// Displays its integer item as 'item N' on a Card whose color is based on
/// the item's value.
///
/// The text is displayed in bright green if [selected] is
/// true. This widget's height is based on the [animation] parameter, it
/// varies from 0 to 128 as the animation varies from 0.0 to 1.0.
class CardItem extends StatelessWidget {
  const CardItem({
    Key? key,
    this.onTap,
    this.selected = false,
    required this.animation,
    required this.item,
  })   : assert(item >= 0),
        super(key: key);

  final Animation<double> animation;
  final VoidCallback? onTap;
  final int item;
  final bool selected;

  @override
  Widget build(BuildContext context) {
    TextStyle textStyle = Theme.of(context).textTheme.headline4!;
    if (selected)
      textStyle = textStyle.copyWith(color: Colors.lightGreenAccent[400]);
    return Padding(
      padding: const EdgeInsets.all(2.0),
      child: SizeTransition(
        axis: Axis.vertical,
        sizeFactor: animation,
        child: GestureDetector(
          behavior: HitTestBehavior.opaque,
          onTap: onTap,
          child: SizedBox(
            height: 80.0,
            child: Card(
              color: Colors.primaries[item % Colors.primaries.length],
              child: Center(
                child: Text('Item $item', style: textStyle),
              ),
            ),
          ),
        ),
      ),
    );
  }
}


///AnimatedList的颤振代码示例
//此示例应用程序使用[AnimatedList]在以下情况下创建效果:
//项目将被删除或添加到列表中。
导入“dart:async”;
进口“包装:颤振/基础.dart”;
进口“包装:颤振/材料.省道”;
void main(){
runApp(const AnimatedListSample());
}
类AnimatedListSample扩展StatefulWidget{
const AnimatedListSample({Key?Key}):super(Key:Key);
@凌驾
_AnimatedListSampleState createState()=>_AnimatedListSampleState();
}
类_AnimatedListSampleState扩展状态{
最终的GlobalKey _listKey=GlobalKey();
后期列表模型_列表;
int?\u选择editem;
晚整数
_nextItem;//用户按下“+”按钮时插入的下一项。
定时器?\ u定时器;
@凌驾
void initState(){
super.initState();
_列表=列表模型(
listKey:_listKey,
初始项:[0,1,2],
removedItemBuilder:\u buildRemovedItem,
);
_nextItem=3;
startTimer();
}
void startTimer(){
const oneSec=const持续时间(毫秒:1000);
_定时器=新定时器。周期性(
一秒,
(计时器){
_插入();
如果(_list.length==10){
timer.cancel();
}
},
);
}
@凌驾
无效处置(){
_计时器!.cancel();
super.dispose();
}
//用于生成尚未删除的列表项。
Widget\u buildItem(
BuildContext上下文、int索引、动画){
回程心脏病(
动画:动画,
项目:_列表[索引],
已选择:_selectedItem==_列表[索引],
onTap:(){
设置状态(){
_selectedItem=\u selectedItem==\u列表[索引]?null:\u列表[索引];
});
},
);
}
//用于在从列表中删除项后生成该项。此
//方法,因为删除的项在其
//动画已经完成(尽管它已经发展到这个ListModel的程度)
//相关)。该小部件将由
//[AnimatedListState.removeItem]方法的
//[AnimatedListRemovedItemBuilder]参数。
小部件\u buildRemovedItem(
int项、BuildContext上下文、动画){
回程心脏病(
动画:动画,
项目:项目,,
选择:false,
//这里没有手势检测器:我们不希望移除的项目是交互式的。
);
}
//在列表模型中插入“下一项”。
void_insert(){
最终整数索引=
_selectedItem==null?\u list.length:\u list.indexOf(\u selectedItem!);
_插入(索引,_nextItem++);
}
//从列表模型中删除选定项。
void_remove(){
如果(_selectedItem!=null){
_list.removeAt(_list.indexOf(_selectedItem!));
设置状态(){
_selectedItem=null;
});
}
}
@凌驾
小部件构建(构建上下文){
返回材料PP(
家:脚手架(
appBar:appBar(
标题:常量文本(“动画列表”),
行动:[
图标按钮(
图标:常量图标(图标。添加圆圈),
按下按钮:_插入,
工具提示:“插入新项目”,
),
图标按钮(
图标:常量图标(图标。删除圆圈),
按下按钮:_移除,
工具提示:“删除所选项目”,
),
],
),
主体:填充物(
填充:常数边集全部(16.0),
子:动画列表(
键:_listKey,
initialItemCount:_list.length,
itemBuilder:\u buildItem,
),
),
),
);
}
}
typedef RemovedItemBuilder=小部件函数(
int项、BuildContext上下文、动画);
///使省道[列表]与[动画列表]保持同步。
///
///[insert]和[removeAt]方法适用于内部列表和
///属于[listKey]的动画列表。
///
///该类只公开用户所需的Dart列表API
///示例应用程序。更多的列表方法很容易添加,但是
///“变形”列表必须在以下方面对动画列表进行相同的更改:
///属于[AnimatedListState.insertItem]和[AnimatedList.removeItem]。
类列表模型{
列表模型({
需要此.listKey,
需要此。removedItemBuilder,
Iterable?初始项,
}):_items=List.from(initialItems???[]);
最终GlobalKey列表键;
最终RemovedItemBuilder RemovedItemBuilder;
最终清单项目;
AnimatedListState?获取_animatedList=>listKey.currentState;
无效插入(整数索引,E项){
_项目。插入(索引,项目);
_animatedList!.insertItem(索引);
}
E removeAt(整数索引){
最终删除项目=_items.removeAt(索引);
如果(removedItem!=null){