【问题标题】:how to stop last element jumps when adding element to Animated list将元素添加到动画列表时如何停止最后一个元素跳转
【发布时间】:2021-05-17 02:28:56
【问题描述】:

我正在尝试重新创建 RobinHood 幻灯片编号动画,我将每个数字视为 n 动画列表中的一个项目,当我在列表的开头添加一个数字时,列表中的最后一个项目会收到一个跳转,我不能完全弄清楚如何解决它。

这是每个数字的代码

class NumberColView extends StatefulWidget {
  final int animateTo;

  final bool comma;
  final TextStyle textStyle;
  final Duration duration;
  final Curve curve;

  NumberColView(
      {@required this.animateTo,
      @required this.textStyle,
      @required this.duration,
      this.comma = false,
      @required this.curve})
      : assert(animateTo != null && animateTo >= 0 && animateTo < 10);

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

class _NumberColState extends State<NumberColView>
    with SingleTickerProviderStateMixin {
  ScrollController _scrollController;

  double _elementSize = 0.0;

  @override
  void initState() {
    super.initState();
    print(_elementSize);
    _scrollController = new ScrollController();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _elementSize = _scrollController.position.maxScrollExtent / 10;
      setState(() {});

    });
  }

  @override
  void didUpdateWidget(NumberColView oldWidget) {
    if (oldWidget.animateTo != widget.animateTo) {
      _scrollController.animateTo(_elementSize * widget.animateTo,
          duration: widget.duration, curve: widget.curve);
    }

    super.didUpdateWidget(oldWidget);
  }

  @override
  Widget build(BuildContext context) {
    // print(widget.animateTo);
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        IgnorePointer(
          child: ConstrainedBox(
            constraints: BoxConstraints(maxHeight: _elementSize),
            child: SingleChildScrollView(
              controller: _scrollController,
              child: Column(
                children: List.generate(10, (position) {
                  return Text(position.toString(), style: widget.textStyle);
                }),
              ),
            ),
          ),
        ),
        widget.comma
            ? Container(
                child: Text(', ',
                    style:
                        TextStyle(fontSize: 16, fontWeight: FontWeight.bold)))
            : Container(),
      ],
    );
  }
}

这是构建整数的代码

class _NumberSlideAnimationState extends State<NumberSlideAnimation> {
  @override
  void didUpdateWidget(oldWidget) {
    if (oldWidget.number.length != widget.number.length) {
      int newLen = widget.number.length - oldWidget.number.length;
      if(newLen > 0) {
        widget.listKey.currentState.insertItem(0,
                            duration: const Duration(milliseconds: 200));
        
      }
      // setState(() {
      //   animateTo = widget.animateTo;
      // });
    }

    super.didUpdateWidget(oldWidget);
  }

  Widget digitSlide(BuildContext context, int position, animation) {
    int item = int.parse(widget.number[position]);
    return SlideTransition(
      position: Tween<Offset>(
        begin: const Offset(0, 1),
        end: Offset(0, 0),
      ).animate(animation),
      child:
          // TestCol(animateTo: item, style: widget.textStyle)

          NumberColView(
        textStyle: widget.textStyle,
        duration: widget.duration,
        curve: widget.curve,
        comma: (widget.number.length - 1) != position &&
                (widget.number.length - position) % 3 == 1 ??
            true,
        animateTo: item,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 40,
      child: AnimatedList(
        shrinkWrap: true,
        scrollDirection: Axis.horizontal,
        key: widget.listKey,
        initialItemCount: widget.number.length,
        itemBuilder: (context, position, animation) {
          return digitSlide(context, position, animation);
        },
      ),
    );
  }
}

【问题讨论】:

标签: flutter flutter-layout flutter-animation


【解决方案1】:

我不知道您的问题的正确解决方案,但是我知道另一种方法,我只是分享它。

这里是完整的代码如果你想使用这个方法:

更新:现在 0 将按照应有的水平从底部出现,并且未充电的值将在那里的宫殿中。

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

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

class _CountState extends State<Count> {
  int count = 10;
  int count2 = 10;
  int count3 = 10;
  Alignment alignment = Alignment.topCenter;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          ClipRRect(
            child: Align(
              alignment: Alignment.center,
              heightFactor: 0.2,
              child: SizedBox(
                height: 100,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    ...List.generate(count.toString().length, (index) {
                      final num2IndexInRange =
                          count2.toString().length - 1 >= index;
                      final num3IndexInRange =
                          count3.toString().length - 1 >= index;

                      final num1 = int.parse(count.toString()[index]),
                          num2 = num2IndexInRange
                              ? int.parse(count2.toString()[index])
                              : 9,
                          num3 = num3IndexInRange
                              ? int.parse(count3.toString()[index])
                              : 1;

                      return AnimatedAlign(
                        key: Key("${num2} ${index}"),
                        duration: Duration(milliseconds: 500),
                        alignment: (num1 != num2 || num1 != num3)
                            ? alignment
                            : Alignment.center,
                        child: Text(
                          num3.toString(),
                          style: TextStyle(
                            fontSize: 20,
                          ),
                        ),
                      );
                    }),
                  ],
                ),
              ),
            ),
          ),
          SizedBox(height: 200),
          RaisedButton(
            onPressed: () async {
              setState(() {
                alignment = Alignment.topCenter;
                count += 10;
              });
              await Future.delayed(Duration(milliseconds: 250));
              setState(() {
                alignment = Alignment.bottomCenter;
                count2 = count;
              });
              await Future.delayed(Duration(milliseconds: 250));
              setState(() {
                count3 = count;
              });
            },
          ),
        ],
      ),
    );
  }
}

如果您不喜欢数字之间的间距如何变化,您可以使用大小调整的框扭曲文本小部件并为其提供固定宽度。

【讨论】:

  • 这不是我想要的,但它可能会给我一些见解,您能否尝试将未收到任何更改的0s 保留在同一个地方(最后一个)并且只有动画0 从 9 -> 0 变化
  • 抱歉来晚了,答案更新了但是截图是旧的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-27
  • 2021-03-05
  • 2019-08-19
  • 2014-06-08
  • 2021-07-09
  • 1970-01-01
相关资源
最近更新 更多