skip to Main Content

The following code does not work since I believe Tweens do not work with null values:

import 'package:flutter/material.dart';

class AnimatedStackDemo extends StatefulWidget {
  @override
  AnimatedStackDemoState createState() => AnimatedStackDemoState();
}

class AnimatedStackDemoState extends State<AnimatedStackDemo> {
  bool _isAnimated = false;

  void _toggleAnimation() {
    setState(() {
      _isAnimated = !_isAnimated;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Animated Stack Demo'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _toggleAnimation,
        child: Icon(Icons.add),
      ),
      body: Stack(
        children: [
          AnimatedPositioned(
            width: 200.0,
            height: 200.0,
            duration: Duration(milliseconds: 500),
            top: _isAnimated ? null : -200.0,
            bottom: _isAnimated ? -200.0 : null,
            child: Container(
              color: Colors.blue,
              width: 200.0,
              height: 200.0,
            ),
          ),
        ],
      ),
    );
  }
}

void main() {
  runApp(MaterialApp(
    home: AnimatedStackDemo(),
  ));
}

How can I accomplish this? I want to take advantage of the stack Widget so I don’t want to use max constraints/screen size, only relative values of the stack (top, bottom, left, right, height and width).

Edit: I should have made explicit that I want to start top: -widgetSize and end at bottom: -widgetSize.

2

Answers


  1. You can use AnimatedAlign widget.

    AnimatedAlign(
      alignment: _isAnimated ? Alignment.topLeft : Alignment.bottomLeft,
      duration: Duration(seconds: 1),
      child: Container(
        width: 200.0,
        height: 200.0,
        color: Colors.blue,
      ),
    ),
    
    Login or Signup to reply.
  2. You can implement the desired behaviour by only using one param (top, or bottom) and then using the height of the Stack inside of your calculations as well. This can be done by wrapping the Stack inside of a LayoutBuilder, so that they size of the Stack is used and not the max Screen size.

    So you start at for example top –childHeight and animate to stackHeight + height.

    Here is your modified example:

    import 'package:flutter/material.dart';
    
    class AnimatedStackDemo extends StatefulWidget {
      @override
      AnimatedStackDemoState createState() => AnimatedStackDemoState();
    }
    
    class AnimatedStackDemoState extends State<AnimatedStackDemo> {
      bool _isAnimated = false;
    
      void _toggleAnimation() {
        setState(() {
          _isAnimated = !_isAnimated;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('Animated Stack Demo'),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: _toggleAnimation,
            child: const Icon(Icons.add),
          ),
          body: SizedBox(
            width: 400,
            height: 400,
            child: LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) {
              return Stack(
                children: <Widget>[
                  Container(color: Colors.green),
                  buildAnimatedChild(200, 200, constraints.maxHeight),
                ],
              );
            }),
          ),
        );
      }
    
      Widget buildAnimatedChild(double width, double height, double maxHeight) {
        return AnimatedPositioned(
          width: width,
          height: height,
          duration: const Duration(milliseconds: 500),
          top: _isAnimated ? maxHeight + height : -height,
          child: Container(
            color: Colors.blue,
            width: width,
            height: height,
          ),
        );
      }
    }
    
    void main() {
      runApp(MaterialApp(
        home: AnimatedStackDemo(),
      ));
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search