O AnimatedContainer tem todas as propriedades do Widget Container apenas acrescentando alguns parametros para definir as animações. Mas como que essas animações acontecem? Simples por interpolação.

Ou seja, cada mudança feita no Widget (cores, largura, altura e até decoration) vão ser interpoladas até chegar no valor alterado. Por exemplo: Se o width for 150.0 e for alterado pra 200, o AnimatedContainer fará um calculo de progressão para ir de 150.0 à 200.0 fazendo o efeito de animação.

Tudo é muito simples, basta alterar a variável e chamar o setState que o AnimatedContainer faz a mágica.

Observe o exemplo a baixo:

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Home(),
    );
  }
}

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  double height = 200.0;

  _onPressed() {
    setState(() {
      if (height == 500.0) {
        height = 200.0;
      } else {
        height += 50.0;
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("AnimatedContainer"),
      ),
      body: Center(
          child: AnimatedContainer(
        width: 200.0,
        height: height,
        color: Colors.red,
        duration: Duration(milliseconds: 500),
        child: Center(
          child: FlutterLogo(),
        ),
      )),
      floatingActionButton: FloatingActionButton(
        onPressed: _onPressed,
        child: Icon(Icons.add),
      ),
    );
  }
}

Ao pressionar o floatingButton ele acrescenta +50 no height e quando chegar a 500 ele volta pra 200. Simples não é?