简体   繁体   English

使用 Flutter 定位小部件动画

[英]Positioned Widget Animation with Flutter

I have the following code in place to animate a Positioned widgets, position, when a pan ends.我有以下代码可以在平移结束时为Positioned小部件、位置设置动画。 However, it doesn't animate.但是,它没有动画。

Initialising AnimationController and variables:初始化AnimationController和变量:

  AnimationController nodesListAnimationController;
  Animation<double> nodesListAnimation;

  double nodesListOffsetY = 0.0; //widget default offset (will be large, but acts like 0.0)
  double nodesListDragOffsetY = 0.0; //how far we have moved the widget from default offset (nodesListOffsetY)
  double nodesListTouchOffset = 0.0; //the initial touch when drag begins
  final double nodesListHeight = 350.0; //widget height

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

    nodesListAnimationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 350),
    )
    ..addListener((){
      setState(() {

      });
    });

  }

Build function;构建功能; See the Positioned widget.请参阅Positioned小部件。 I can drag this up and down within the bound I have created using the panning callbacks on GestureDetector .我可以使用GestureDetector上的平移回调在我创建的范围内上下拖动它。

When the pan ends, I want to animate the Positioned widget back to a given position.当平移结束时,我想将Positioned小部件动画回给定位置。 Currently, no animation occurs.目前,没有动画发生。

@override
  Widget build(BuildContext context) {
    nodesListOffsetY = MediaQuery.of(context).size.width + 110.0;

    AppBar appBar = AppBar(
      ...
    );

    return Scaffold(
        appBar: appBar,
        backgroundColor: Colors.black,
        body: Stack(
          children: <Widget>[
            Column(
              children: <Widget>[
                cameraWidget(),
                cameraControls(),
              ],
            ),
            Positioned(
              left: 0.0,
              top: nodesListAnimationController.isAnimating ? nodesListAnimation.value : nodesListOffsetY + nodesListDragOffsetY,
              width: MediaQuery.of(context).size.width,
              height: nodesListHeight,
              child: GestureDetector(
                onPanStart: (dragDetails) {
                  nodesListTouchOffset = (dragDetails.globalPosition.dy - appBar.preferredSize.height) - nodesListOffsetY - nodesListDragOffsetY;
                },
                onPanUpdate: (dragDetails) {
                  setState(() {
                    double newDragOffset = (dragDetails.globalPosition.dy - nodesListOffsetY) - appBar.preferredSize.height - nodesListTouchOffset;

                    //allow it only to move up if is clips off screen, otherwise upper limit not needed
                    double nodesListVisible = ((MediaQuery.of(context).size.height - appBar.preferredSize.height) - nodesListOffsetY);
                    bool isClipping = nodesListVisible < nodesListHeight ? true : false;
                    double upperLimit = 0.0;
                    if (isClipping) upperLimit = -(nodesListHeight - nodesListVisible);

                    //limit drag bounds. don't drag too high or low.
                    if (newDragOffset < upperLimit) newDragOffset = upperLimit;
                    else if (newDragOffset > 0) newDragOffset = 0.0;
                    else nodesListDragOffsetY = newDragOffset;
                  });
                },
                onPanEnd: (dragDetails) {
                  double currentPos = (nodesListOffsetY + nodesListDragOffsetY);
                  nodesListAnimation = Tween(begin: currentPos, end: nodesListOffsetY).animate(nodesListAnimationController);
                  nodesListAnimationController.forward(from: currentPos);
                  nodesListAnimation.addStatusListener((state) {
                    print(nodesListAnimation.value);
                  });
                },
                child: nodesList(),
              ),
            ),
          ],
        ));
  }

Late to the party, but your issue is because of:聚会迟到,但您的问题是因为:

nodesListAnimationController.forward(from: currentPos)

Whose from is incorrectly accepting a value outside of 0.0-1.0 .谁的from错误地接受了0.0-1.0之外的值。 So you should probably change it to just controller.forward()所以你应该把它改成controller.forward()

This isn't well documented, but forward's from is meant to accept values from 0.0-1.0 , or more specifically, if set, then the range provided by lowerBound and upperBound (with few exceptions).这没有得到很好的记录,但是 forward 的from旨在接受0.0-1.0 之间的值,或者更具体地说,如果设置了,则由lowerBoundupperBound提供的范围(少数例外)。 ( you can also think of it as 0-100% ). 您也可以将其视为 0-100% )。 It is not meant to accept the value range from the Tween's begin and end , nor is it aware of that range.它并不意味着接受 Tween 的beginend的值范围,也不知道该范围。

https://api.flutter.dev/flutter/animation/AnimationController-class.html https://api.flutter.dev/flutter/animation/AnimationController-class.html

By default, an AnimationController linearly produces values that range from 0.0 to 1.0默认情况下,AnimationController 线性地产生范围从 0.0 到 1.0 的值

https://flutter.dev/docs/development/ui/animations/overview#addstatuslistener https://flutter.dev/docs/development/ui/animations/overview#addstatuslistener

An animation might then run forward (eg, from 0.0 to 1.0)然后动画可能会向前运行(例如,从 0.0 到 1.0)

(And I can verify that after I changed your code to use just .forward() , I was able to see it animate) (并且我可以验证在我将您的代码更改为仅使用.forward() ,我能够看到它的动画)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM