Flutter slideTransition is not animating
Asked Answered
R

1

13

So I'm trying to create a trivial slide transition element in flutter and I'm having some difficulty. What the below does is wait for the animation time, and then just display the Text("hello there sailor"). I don't know why this is not animating - it seems very similar to this previous post that has a trivial example (Sliding animation to bottom in flutter).

This is how I call the below code: DeleteCheck(offsetBool: widget.model.deleteNotify, widthSlide: 0.50*width100) where double width100 = MediaQuery.of(context).size.width;.

Does anyone see what I am doing wrong?

class DeleteCheck extends StatefulWidget{

  final offsetBool;
  final double widthSlide;

  DeleteCheck({
    Key key, 
    this.offsetBool, 
    this.widthSlide
  }): super(key: key);

  @override 
  State<StatefulWidget> createState() {
    return new _MyDeleteCheck();
  }
}

class _MyDeleteCheck extends State<DeleteCheck> with TickerProviderStateMixin {
  AnimationController _controller;
  Animation<Offset> _offsetFloat; 

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

    _controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 1),
    );

    _offsetFloat = Tween<Offset>(begin: Offset(widget.widthSlide, 0.0), end: Offset.zero)
        .animate(_controller);

    _offsetFloat.addListener((){
      setState((){});
    });

    _controller.forward();

  }

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

  @override
  Widget build(BuildContext context) {
    double height100 = MediaQuery.of(context).size.height;
    double width100 = MediaQuery.of(context).size.width;
    return new SlideTransition(
      position: _offsetFloat,
      child: Container(
        color: Colors.cyan,
        width: 0.525*width100-3.0,
        child: Text("hello there sailor")
      )
    );
  }
}
Rudbeckia answered 15/11, 2018 at 22:4 Comment(3)
did you try to print _offsetFloat inside listener ? whats the Offset value?Oratorical
I'm on pskinks side Here. Looks like the _offsetFloat could not be initialized with a non Zero value. I'll debug over it, when I've got my IDE ready. Also I'd like to note that the animation will probably be a huge slide, because the Offset is relative to the size of the child Widget of SlideTransition. Therefore an Offset of (1,1), is equal to an absolut Offset of the whole Widget length and width.Galvanoscope
What a truly weird API the "Offset" class is. Far less elegant than constraint based layout. It assumes that you always know the height / width of whatever widget you're trying to Offset. Not only is that rarely true in a declarative framework like Flutter, but, it's also imprecise even if you DID know. Try placing a widget off screen using the Offset in a SlideTransition. A constraint approach would define the relationship explicitly. Offset is a crude tool, that barely works.Milano
G
26

I have good news for you! Your code is working! :) The animation looks like it is not happening, because the distance it moves is huge. The Offset, passed to the SlideTransition, is relative to its childs size. For example your child has width: 100.0 and you offset with Offset(2.0, 0.0), your child will have moved 200.0 pixels to the right.

Just try to change begin: Offset(widget.widthSlide, 0.0), end: Offset.zero to begin: Offset(2.0, 0.0), end: Offset.zero. You'll see the text slowly animating from the right to the center of the screen. Therefore you just need to adjust your parameterisation.

SlideTransition changed

Anyway here are some additional suggestions for optimizing your code:

  • If you are using prebuilt AnimatedWidgets like the SlideTransition, you do not need to call addListener with setState on the controller. The AnimatedWidget takes care of it by itself. Hence you can remove the follwing lines:

lines:

_offsetFloat.addListener((){
  setState((){});
});
  • Also it is not necessary to call const constructors. You can just leave this keyword out like new. The compiler will optimize and choose the right constructor in each case.
Galvanoscope answered 16/11, 2018 at 8:0 Comment(2)
I hope it's obvious to everyone why simply changing it to Offset(2.0,0.0) is a bad solution. How would this behave on arbitrary screen size? Let's say you're running your App on an iPad Pro, or maybe you're compiling for Desktop and it's running on a 34" monitor. The Offset now needs to be much more than Offset(2.0,0.0).....Milano
That's not available when the app loads... nor do you know the height (or width) of all sub-widgets. Some of the components in flutter tend to auto-size themselves... So how would you go about knowing the exact offset you need? Even if you could get the MediaQuery at app load (which requires an akward Future) ... then you'd still somehow need to know the exact height/width of your widget in order to properly compute the correct offset. This is a pretty terrible way of doing this. Constraints would be a much more explicit and intuitive approach. Not a criticism of your solution! Flutter.Milano

© 2022 - 2024 — McMap. All rights reserved.