Home > Blockchain >  Flutter: Animate a widget's height back to its original content height
Flutter: Animate a widget's height back to its original content height

Time:11-15

I've always wondered about this seeing as AnimatedContainer is pretty flexible. What got me confused is if we can animate a Container to be smaller than the actual content, how do we tell it to go back to the default content height? This being the height of the content is dependent on what is inside it.

I have no real use case for this right now but I can see this being used if, for example, the container had a `ListView' inside (hereby not showing the offset error).

I tried using null but apparently it can't be nullable.

double height = 100;

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: GestureDetector(
      onTap: () {
        setState(() {
          height = height == 100 ? null : 100;
        });
      },
      child: Center(
        child: AnimatedContainer(
          curve: Curves.bounceOut,
          duration: const Duration(milliseconds: 500),
          width: 100,
          height: height,
          color: Colors.deepPurple,
          child: Text('This text set to be much larger than 100 aaaaaaaaaa aaaaaaaa aaaaaaaaa aaaaaaaa.',
            style: TextStyle(
              fontSize: 30,
              color: Colors.white,
            )
          )
        ),
      ),
    )
  );
}

Error

Error: A value of type 'double?' can't be assigned to a variable of type 'double' because 'double?' is nullable and 'double' isn't.
            height = height == 100 ? null : 100;

I'm trying to approach this through implicit animation but I'm guessing the answer would be an explicit one. Hoping to hear what you guys have in mind.

Edit:

Not used here but the same problem applies to using Tween<double>(begin: 100, end: null).animate(_somecontroller); where null is not a valid argument.

CodePudding user response:

You are passing null to the height variable when you defined it as non-nullable, change your variable to this:

double? height = 100;

but you can't use bounded and unbounded height for AnimatedContainer, this is full example of what you can do:

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

  @override
  State<TestAnimation> createState() => _TestAnimationState();
}

class _TestAnimationState extends State<TestAnimation> {
  double? height;
  GlobalKey textKey = GlobalKey();
  double textHeight = 0.0;

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

    WidgetsBinding.instance.addPostFrameCallback((_) {
      setState(() {
        final textKeyContext = textKey.currentContext;
        if (textKeyContext != null) {
          final box = textKeyContext.findRenderObject() as RenderBox;
          textHeight = box.size.height;
          height = textHeight;
        }
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: GestureDetector(
      onTap: () {
        setState(() {
          height = height == 100 ? textHeight : 100;
        });
      },
      child: Center(
        child: AnimatedContainer(
          constraints: const BoxConstraints(
            maxHeight: 1000,
          ),
          curve: Curves.bounceOut,
          duration: const Duration(milliseconds: 500),
          width: 100,
          height: height,
          color: Colors.deepPurple,
          child: Text(
            'This text set to be much larger than 100 aaaaaaaaaa aaaaaaaa aaaaaaaaa aaaaaaaa.',
            key: textKey,
            style: TextStyle(
              fontSize: 30,
              color: Colors.white,
            ),
          ),
        ),
      ),
    ));
  }
}

enter image description here

  • Related